Python 我是否理解os.walk right?

Python 我是否理解os.walk right?,python,file,Python,File,os.walk(startdir)中的root、dir、file循环通过以下步骤工作 for root in os.walk(startdir) for dir in root for files in dir 获取开始目录的根目录:C:\dir1\dir2\startdir 获取C:\dir1\dir2\startdir中的文件夹并返回文件夹列表“dirlist” 获取第一个目录列表项中的文件,并将文件列表“filelist”作为文件列表的第一项返回 移动到目录列

os.walk(startdir)
中的root、dir、file循环通过以下步骤工作

for root in os.walk(startdir) 
    for dir in root 
        for files in dir
  • 获取开始目录的根目录:C:\dir1\dir2\startdir

  • 获取C:\dir1\dir2\startdir中的文件夹并返回文件夹列表“dirlist”

  • 获取第一个目录列表项中的文件,并将文件列表“filelist”作为文件列表的第一项返回

  • 移动到目录列表中的第二项,并将此文件夹中的文件列表“filelist2”作为文件列表的第二项返回。等等

  • 移动到foldertree中的下一个根目录并从2开始。等等


  • 对吧??或者它只是先得到所有根,然后是所有目录,然后是所有文件?

    os.walk的工作原理与上面的略有不同。基本上,它返回(路径、目录、文件)的元组。要查看此信息,请尝试以下操作:

    import pprint
    import os
    pp=pprint.PrettyPrinter(indent=4)
    for dir_tuple in os.walk("/root"):
        pp.pprint(dir_tuple)
    

    …您将看到循环的每一次迭代都将打印一个目录名、该目录中任何目录的名称列表,以及该目录中所有文件的另一个列表。然后,os.walk将进入子目录列表中的每个目录,并执行相同的操作,直到遍历了原始根目录的所有子目录。了解一点递归可能有助于理解它是如何工作的。

    这里有一个简单的示例,说明如何工作,并使用一些函数进行解释

    首先请注意,它返回三项:根目录、当前根目录下的目录列表(
    dirs
    )以及在这些目录中找到的文件列表。网站将为您提供更多信息

    dirs
    将包含根目录下的目录列表,而文件将包含在这些目录中找到的所有文件的列表。在下一次迭代中,上一个
    dirs
    列表中的每个目录将依次扮演
    root
    的角色,搜索将从那里继续,仅在搜索当前级别后才向下搜索一个级别

    代码示例:这将搜索、计数和打印指定搜索目录(根目录)下
    .jpg
    .gif
    文件的名称。它还使用函数将文件的基文件与其扩展名分开,并使用函数为您提供全名,包括找到的图像文件的路径

    import os
    
    searchdir = r'C:\your_root_dir'  # your search starts in this directory (your root) 
    
    count = 0
    for root, dirs, files in os.walk(searchdir):
        for name in files:
            (base, ext) = os.path.splitext(name) # split base and extension
            if ext in ('.jpg', '.gif'):          # check the extension
                count += 1
                full_name = os.path.join(root, name) # create full path
                print(full_name)
    
    print('\ntotal number of .jpg and .gif files found: %d' % count)
    

    os.walk
    返回一个生成器,该生成器创建一个值元组(当前路径、当前路径中的目录、当前路径中的文件)

    每次调用生成器时,它都会递归地跟踪每个目录,直到调用walk的初始目录中没有其他子目录可用为止

    因此,

    os.walk('C:\dir1\dir2\startdir').next()[0] # returns 'C:\dir1\dir2\startdir'
    os.walk('C:\dir1\dir2\startdir').next()[1] # returns all the dirs in 'C:\dir1\dir2\startdir'
    os.walk('C:\dir1\dir2\startdir').next()[2] # returns all the files in 'C:\dir1\dir2\startdir'
    
    所以

    还是这个

    def search_file(directory = None, file = None):
        assert os.path.isdir(directory)
        for cur_path, directories, files in os.walk(directory):
            if file in files:
                return os.path.join(directory, cur_path, file)
        return None
    
    或者,如果要查找文件,可以执行以下操作:

    import os
    def search_file(directory = None, file = None):
        assert os.path.isdir(directory)
        current_path, directories, files = os.walk(directory).next()
        if file in files:
            return os.path.join(directory, file)
        elif directories == '':
            return None
        else:
            for new_directory in directories:
                result = search_file(directory = os.path.join(directory, new_directory), file = file)
                if result:
                    return result
            return None
    
    简单地说,os.walk()将生成路径、文件夹和给定路径中存在的文件的元组,并将继续遍历子文件夹

    import os.path
    path=input(" enter the path\n")
    for path,subdir,files in os.walk(path):
       for name in subdir:
           print os.path.join(path,name) # will print path of directories
       for name in files:    
           print os.path.join(path,name) # will print path of files
    

    这将生成所有子目录、文件和子目录中文件的路径

    最小可运行示例

    这就是我喜欢学习的方式:

    mkdir root
    cd root
    mkdir \
      d0 \
      d1 \
      d0/d0_d1
    touch \
      f0 \
      d0/d0_f0 \
      d0/d0_f1 \
      d0/d0_d1/d0_d1_f0
    tree
    
    输出:

    .
    ├── d0
    │   ├── d0_d1
    │   │   └── d0_d1_f0
    │   ├── d0_f0
    │   └── d0_f1
    ├── d1
    └── f0
    
    'root' ['d0', 'd1'] ['f0']
    'root/d0' ['d0_d1'] ['d0_f0', 'd0_f1']
    'root/d0/d0_d1' [] ['d0_d1_f0']
    'root/d1' [] []
    
    main.py

    #!/usr/bin/env python3
    import os
    for path, dirnames, filenames in os.walk('root'):
        print('{} {} {}'.format(repr(path), repr(dirnames), repr(filenames)))
    
    输出:

    .
    ├── d0
    │   ├── d0_d1
    │   │   └── d0_d1_f0
    │   ├── d0_f0
    │   └── d0_f1
    ├── d1
    └── f0
    
    'root' ['d0', 'd1'] ['f0']
    'root/d0' ['d0_d1'] ['d0_f0', 'd0_f1']
    'root/d0/d0_d1' [] ['d0_d1_f0']
    'root/d1' [] []
    
    这说明了一切:

    • path
      是每个步骤的根目录
    • dirnames
      是每个
      path
    • filenames
      是每个
      路径中的文件基名称列表
    在Ubuntu 16.04、Python 3.5.2上测试

    修改
    dirnames
    更改树递归

    这基本上是你唯一需要记住的事情

    例如,如果对
    dirnames
    执行以下操作,则会影响遍历:

    漫游文件或目录

    如果要遍历的输入是文件或目录,则可以如下处理:

    #!/usr/bin/env python3
    
    import os
    import sys
    
    def walk_file_or_dir(root):
        if os.path.isfile(root):
            dirname, basename = os.path.split(root)
            yield dirname, [], [basename]
        else:
            for path, dirnames, filenames in os.walk(root):
                yield path, dirnames, filenames
    
    for path, dirnames, filenames in walk_file_or_dir(sys.argv[1]):
        print(path, dirnames, filenames)
    

    我喜欢os.path解决方案,因此os.path将始终对应于os.WACK在迭代过程中所在的目录?顺便说一句,以上所有答案都值得一个答案标签,但我只能将其中一篇文章标记为答案!糟糕,或者有没有办法将多篇文章标记为答案?哦,还有一件事,为什么要导入os和os.path?导入操作系统时不包括os.path吗?操作系统模块是一个beast 23k行,但是是的
    导入操作系统。虽然我记得我曾经遇到过一个问题,但不记得是什么问题,但是不需要path,any way os.path是处理路径的最安全的方法
    os.path.join
    它将自动生成适当的
    join
    在任何操作系统中,在windows中它知道它们应该“\”并在*nix中转义它知道它们应该是
    /
    ,并且它知道何时组合目录或只是文件,它非常聪明:)Python3注意:下一步(os.walk('C:\dir1\dir2\startdir'))[0]以防其他人在搜索os.walk和“宽度优先”后偶然发现它-上述信息不正确。walk(至少在Python2.6和2.7中)执行深度优先遍历,而不是宽度优先遍历。项目生成的确切顺序取决于topdown参数-如果topdown为True(默认),则它执行预排序深度优先遍历(),如果为False,则执行后排序深度优先遍历()。