在 POSIX 或 Windows 中,您无法在一次操作系统调用中获取所有数据。opendir
对于 POSIX,每个目录( , readdir
, )至少有三个close
,每个目录条目(stat
)加上一个。
我相信接下来的内容将导致操作系统调用少于您发布的内容。是的,os.walk()
调用是懒惰的;也就是说,整个树在从 的返回时不在walk()
内存中,而是在对 的调用期间被零散地读取next()
。
因此,我的版本将只读取一阶后代目录,并且stat
只读取直系子孙目录。您的版本也适用于所有曾孙,只要您的目录结构有多深。
root='.'
grandChildren = []
for kid in next(os.walk('.'))[1]:
x = next(os.walk(os.path.join('.', kid)))
for grandKid in x[1]: # (or x[1]+x[2] if you care about regular files)
grandChildren.append(os.path.join(x[0], grandKid))
或者,作为列表推导而不是 for 循环:
import os
root='.'
grandChildren = [
os.path.join(kid, grandKid)
for kid in next(os.walk(root))[1]
for grandKid in next(os.walk(os.path.join(root, kid)))[1]]
最后,将os.walk
s 分解为一个函数:
def read_subdirs(dir='.'):
import os
return (os.path.join(dir,x) for x in next(os.walk(dir))[1])
root='.'
grandChildren = [
grandKid
for kid in read_subdirs(root)
for grandKid in read_subdirs(kid)]
通过测试,我们可以看到,
stat
如果有曾孙,我的版本调用次数比你的要少得多。
例如,在我的主目录中,我运行了我的代码 ( /tmp/a.py
) 和你的 ( /tmp/b.py
),在每种情况下都root
设置为:'.'
$ strace -e stat python /tmp/a.py 2>&1 > /dev/null | egrep -c stat
1245
$ strace -e stat python /tmp/b.py 2>&1 > /dev/null | egrep -c stat
36049