在 POSIX 和 Windows 中,你不能通过一个操作系统调用获取所有这些数据。至少对于 POSIX,每个目录需要三个调用(
opendir
、
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]:
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
提取到一个函数中:
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
unipath
模块了吗? - Henrik Andersson