我对 os.walk 的理解正确吗?
- 2025-03-19 08:57:00
- admin 原创
- 50
问题描述:
根、目录、文件的循环os.walk(startdir)
通过这些步骤完成吗?
for root in os.walk(startdir)
for dir in root
for files in dir
获取启动目录的根目录:C:\dir1\dir2\startdir
获取 C:\dir1\dir2\startdir 中的文件夹并返回文件夹列表“dirlist”
获取第一个目录列表项中的文件,并返回文件列表“filelist”作为文件列表列表的第一项。
移动到 dirlist 中的第二项,并返回此文件夹“filelist2”中的文件列表作为文件列表的第二项。等等。
移动到文件夹树中的下一个根并从 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
扫码咨询,免费领取项目管理大礼包!