试图找出为什么Python递归创建dirs

时间:2018-06-19 00:02:33

标签: python os.walk

我有一个包含许多子目录的目录。这是我的代码:

def organiseData():
    for root, dirs, files in os.walk(directory_name):
        for dirName in sorted(dirs):
            print(root + '/' + dirName)
            if not os.path.exists(root + '/' + dirName + '/xml'):
                os.mkdir(root + '/' + dirName + '/xml')

它会在每个子目录中创建目录,但是然后在列表的第一个子目录中,它会以递归方式在xml dirs中创建xml目录,直到:

Sequence_3525/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml/xml
Traceback (most recent call last):
File "organiseData.py", line 74, in <module>
organiseData()
File "organiseData.py", line 8, in organiseData
for root, dirs, files in os.walk(directory_name):

RecursionError: maximum recursion depth exceeded

2 个答案:

答案 0 :(得分:3)

dirs产生的os.walk值表示在以下迭代中遍历的目录列表(请参阅this for an example of why that's useful)。

每次在dirs的目录中创建新的xml文件夹时,os.walk稍后会进入新目录并创建更多xml文件夹,因为您创建的文件夹是空的。

请尝试在root级别进行检查。例如:

def organize_data(directory_name):
    for root, subdirs, filenames in os.walk(directory_name):
        for sub in sorted(subdirs):
            print(os.path.join(root, sub))
        xml_dir = os.path.join(root, 'xml')
        if not os.path.exists(xml_dir):
            os.mkdir(xml_dir)

解决此问题的另一种方法是通过删除您已经创建了xml文件夹的所有目录来修剪dirs。像这样:

def organize_data(directory_name):
    for root, dirs, filenamess in os.walk(directory_name):
        for dir_name in sorted(dirs):
            print(os.path.join(root, dir_name))
            xml_dir = os.path.join(root, dir_name, 'xml')
            if not os.path.exists(xml_dir):
                os.mkdir(xml_dir)
                dirs.remove(dir_name) # Prevents infinite loop

答案 1 :(得分:2)

默认情况下,目录从上到下遍历。由于您在子目录中创建目录,因此您将继续查找更多目录。自下而上搜索:

os.walk(...,topdown=False)

由于搜索将从最深的目录开始,因此添加更深的xml目录不会影响迭代。

来自documentation

的引用
  

如果可选参数topdown为True或未指定,则为三元组   在任何一个三元组之前生成一个目录   子目录(目录从上到下生成)。如果自上而下   错误,目录的三元组是在三元组之后生成的   它的所有子目录(目录都是自下而上生成的)。没有   无论topdown的值如何,都会检索子目录列表   在目录及其子目录的元组之前   生成。

     

当topdown为True时,调用者可以就地修改dirnames列表   (可能使用del或slice赋值),而walk()只会递归   进入名称保留在dirnames中的子目录;这可以   用来修剪搜索,强加一个特定的访问顺序,甚至   通知walk()有关调用者创建或重命名的目录   在它再次恢复步行()之前。自上而下修改dirnames   False对步行的行为没有影响,因为在自下而上   模式dirnames中的目录是在dirpath本身之前生成的   是生成的。

同样FYI,os.path.join()是一种更清晰的方式将目录连接在一起,例如os.path.join(root,dirname,'xml')