我对 os.walk 的理解正确吗?

2025-03-19 08:57:00
admin
原创
51
摘要:问题描述:根、目录、文件的循环os.walk(startdir)通过这些步骤完成吗?for root in os.walk(startdir) for dir in root for files in dir 获取启动目录的根目录:C:\dir1\dir2\startdir获取 C...

问题描述:

根、目录、文件的循环os.walk(startdir)通过这些步骤完成吗?

for root in os.walk(startdir) 
    for dir in root 
        for files in dir
  1. 获取启动目录的根目录:C:\dir1\dir2\startdir

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

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

  4. 移动到 dirlist 中的第二项,并返回此文件夹“filelist2”中的文件列表作为文件列表的第二项。等等。

  5. 移动到文件夹树中的下一个根并从 2 开始。等等。

对吧?还是先获取所有根目录,然后获取所有目录,最后获取所有文件?


解决方案 1:

os.walk返回一个生成器,创建一个值元组(current_path、current_path 中的目录、current_path 中的文件)。

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

像这样,

os.walk('C:dir1dir2startdir').next()[0] # returns 'C:dir1dir2startdir'
os.walk('C:dir1dir2startdir').next()[1] # returns all the dirs in 'C:dir1dir2startdir'
os.walk('C:dir1dir2startdir').next()[2] # returns all the files in 'C:dir1dir2startdir'

所以

import os.path
....
for path, directories, files in os.walk('C:dir1dir2startdir'):
     if file in files:
          print('found %s' % os.path.join(path, file))

或者这个

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

解决方案 2:

最小可运行示例

我喜欢这样学习:

mkdir root
cd root
mkdir \n  d0 \n  d1 \n  d0/d0_d1
touch \n  f0 \n  d0/d0_f0 \n  d0/d0_f1 \n  d0/d0_d1/d0_d1_f0
tree

输出:

.
├── d0
│   ├── d0_d1
│   │   └── d0_d1_f0
│   ├── d0_f0
│   └── d0_f1
├── d1
└── f0

主程序

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

输出:

'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是每个文件的基本名称列表path

在 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)

解决方案 3:

简单来说,os.walk() 将生成给定路径中的路径、文件夹、文件的元组,并将继续遍历子文件夹。

import os.path
path=input(" enter the path
")
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

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

解决方案 4:

这是一个关于os.walk()工作原理的简短示例,以及使用一些os函数的一些解释。

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

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

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

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('
total number of .jpg and .gif files found: %d' % count)

解决方案 5:

我的答案非常简单明了。我自己也是个初学者,我在网上搜索(特别是参见docs.python.org 上的优秀文档)并尝试了一些测试代码(例如这个)找到了答案:

for root, dirs, files in os.walk(startdir)
    print ("__________________")
    print (root)
    for file in files:
        print ("---",file)

这将打印出目录树,其中每个目录(起始目录和包含的子目录)前面都有一行,后面是其中包含的文件。

我认为你必须牢记两件事:

(1)os.walk 生成一个三元组(三元组)<root,dirs,filenames>,其中

  • root 是一个包含根目录名称的字符串;

  • dirs 是一个字符串列表:根目录中直接包含的目录名称,即第一级,不包含可能包含的子目录;

  • filenames 是一个字符串列表:root 中直接包含的文件名。

(2)for 循环,例如

for root, subdirs, files in os.walk(YourStartDir)

循环遍历根目录及其所有子目录。它不会对每个文件执行一步;它只是扫描目录树,并在每一步(对于树中的每个目录)填充其中包含的文件名列表和直接包含在其中的子目录列表。如果您有n 个目录(包括根目录及其子目录),则 for 循环将循环n次,即需要n步。您可以编写一小段测试代码来检查这一点,例如使用计数器。在每一步,它都会生成一个 3 元组:一个字符串加上两个(可能为空)字符串列表。在此示例中,3 元组的元素称为:“root”、“subdirs”、“files”,但这些名称由您决定;如果您的代码是

for a, b, c in os.walk(startdir)

3 元组的元素将被称为“a”、“b”、“c”。

我们回到测试代码:

for root, dirs, files in os.walk(startdir)
    print ("__________________")
    print (root)
    for file in files:
        print ("---",file)

第一个循环:root 是您在输入中给出的目录(起始路径,起始目录:一个字符串),dirs 是包含的子目录名称列表(但不是其中包含的目录名称),files 是包含的文件列表。在测试代码中,我们没有使用“dirs”列表。

第二个循环:root 现在是第一个子目录,dirs 是其中包含的子目录的列表,files 是其中包含的文件的列表。

...依此类推,直到到达树中的最后一个子目录。

os.walk 有三个可选参数:您可以在网上找到很多关于它们及其用途的信息,但我认为您的问题是关于 os.walk 的基础知识。

解决方案 6:

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

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

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

解决方案 7:

我觉得下面的解释更清楚:

for path, subdirs, files in os.walk(fold, topdown=False):
    assert set(os.listdir(path)) == set(subdirs + files)

上面的代码没有错误

os.walk() 将浏览所有包含文件夹和文件或仅包含文件的文件夹;它们的文件夹是subdirs变量中的列表;它们的文件是变量中的列表;它们的地址是变量files中的字符串path

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用