os.walk是否利用操作系统返回的文件类型来提高效率?

时间:2013-03-06 22:29:18

标签: python optimization directory

os.walk函数返回目录和文件的单独列表。许多常见操作系统(如Windows和Linux)上的底层OS调用返回一个文件类型或标志,指定每个目录条目是文件还是目录;如果没有此标志,则必须再次为每个返回的文件名查询操作系统。 os.walk的代码是否使用了这些信息,或者它是否像os.listdir那样丢弃了?

2 个答案:

答案 0 :(得分:5)

不,它没有。

在幕后,os.walk()使用os.listdir()os.path.isdir()分别列出文件和目录。请参阅source code of 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)

其中listdirisdiros.listdir()os.path.isdir()函数的模块全局变量。它以递归方式调用自己的子目录。

答案 1 :(得分:2)

正如Martijn Pieters的回答所解释的那样,os.walk只使用os.listdiros.path.isdir

在邮件列表上已经对此进行了几次讨论,但是没有针对stdlib的具体建议。有各种边缘情况使这不像看起来那么微不足道。此外,如果Python 3.4或更高版本增加了一个新的path模块,那么os.walk很可能会被替换/弃用而不是改进。

但是,您可以使用许多第三方模块。

最简单的可能是Ben Hoyt的betterwalk。我相信他打算在PyPI上使用它,甚至可能将它提交给Python 3.4或更高版本,但是目前你必须在github上安装它。 betterwalk提供名为os.listdir的{​​{1}}替换,并在其基础上构建90%完整iterdir_stat替换。在大多数POSIX系统和Win32上,它通常可以避免不必要的os.walk调用。 (在某些情况下,它不能像stat / fts (3) / nftw (3)那样做得好,但最坏的情况是它会做一些不必要的调用,而不是失败。可能不完整,最后我检查过,正在处理符号链接,也许还有错误处理。)

对于POSIX系统来说,find (1)周围还有一个很好的包装器,就现代POSIX系统的性能而言,这显然是理想的 - 但它有一个不同的(更好的,在我看来,但仍然不同)界面,并且不支持Windows或其他平台(甚至更旧的POSIX系统)。

在PyPI和其他地方,还有大约30多个“阳光下的所有东西都与路径有关”模块,其中一些模块具有新的fts类功能。