该os.walk
函数返回目录和文件的单独列表。许多常见操作系统(如 Windows 和 Linux)上的底层操作系统调用返回一个文件类型或标志,指定每个目录条目是文件还是目录;如果没有这个标志,就必须为每个返回的文件名再次查询操作系统。代码是os.walk
使用这些信息还是将其丢弃os.listdir
?
2 回答
不,它没有。
在后台,os.walk()
使用os.listdir()
和os.path.isdir()
分别列出文件和目录。见源代码walk()
。
具体来说:
try:
# Note that listdir and error are globals in this module due
# to earlier import-*.
names = listdir(top)
except error, err:
if onerror is not None:
onerror(err)
return
dirs, nondirs = [], []
for name in names:
if isdir(join(top, name)):
dirs.append(name)
else:
nondirs.append(name)
where listdir
andisdir
是os.listdir()
andos.path.isdir()
函数的模块全局变量。它为子目录递归地调用自己。
正如 Martijn Pieters 的回答所解释的,os.walk
只使用os.listdir
and os.path.isdir
。
在邮件列表上对此进行了几次讨论,但没有针对标准库提出具体建议。有各种边缘情况使这不像看起来那么简单。此外,如果 Python 3.4 或更高版本增加了一个新path
模块,则很有可能os.walk
只是被替换/弃用,而不是就地改进。
但是,您可以使用许多第三方模块。
最简单的可能是 Ben Hoyt 的betterwalk
. 我相信他打算在 PyPI 上得到这个,甚至可能将它提交给 Python 3.4 或更高版本,但目前你必须在 github 上安装它。betterwalk
提供了一个os.listdir
名为 的替代品,并在它之上构建iterdir_stat
了一个 90% 完整的替代品。os.walk
在大多数 POSIX 系统和 Win32 上,它通常可以避免不必要stat
的调用。(在某些情况下它的工作不如fts (3)
/ nftw (3)
/好find (1)
,但在最坏的情况下它只是做了一些不必要的调用,而不是失败。最后我检查的可能不完整的部分正在处理符号链接,可能还有错误处理。)
POSIX 系统还有一个很好的包装器fts
,就现代 POSIX 系统的性能而言,这显然是理想的——但它有一个不同的(在我看来更好,但仍然不同)界面,并且不支持 Windows 或其他平台(甚至更旧的 POSIX 系统)。
PyPI 和其他地方还有大约 30 多个“与路径有关的一切”模块,其中一些具有类似新walk
的功能。