递归函数的屈服

2024-05-23 16:13:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试对给定路径下的所有文件执行操作。我不想事先收集所有的文件名,然后对它们做些什么,所以我尝试了这样做:

import os
import stat

def explore(p):
  s = ''
  list = os.listdir(p)
  for a in list:
    path = p + '/' + a
    stat_info = os.lstat(path )
    if stat.S_ISDIR(stat_info.st_mode):
     explore(path)
    else:
      yield path

if __name__ == "__main__":
  for x in explore('.'):
    print '-->', x

但这段代码在目录被命中时会跳过目录,而不是生成目录的内容。我做错什么了?


Tags: 文件pathinimport路径info目录for
3条回答

使用^{}而不是重新设计轮子。

特别是,遵循库文档中的示例,下面是一个未经测试的尝试:

import os
from os.path import join

def hellothere(somepath):
    for root, dirs, files in os.walk(somepath):
        for curfile in files:
            yield join(root, curfile)


# call and get full list of results:
allfiles = [ x for x in hellothere("...") ]

# iterate over results lazily:
for x in hellothere("..."):
    print x

问题是这行代码:

explore(path)

它是做什么的?

  • 用新的path调用explore
  • explore运行,创建生成器
  • 生成器返回到执行explore(path)的位置。
  • 并被丢弃

为什么要丢弃?它没有被分配给任何东西,也没有被迭代——它被完全忽略了。

如果你想对结果做点什么,那么,你必须对结果做点什么!;)

修复代码的最简单方法是:

for name in explore(path):
    yield name

当您确信您了解正在发生的事情时,您可能需要使用os.walk()

一旦您迁移到Python 3.3(假设所有工作都按计划进行),您将能够使用新的yield from语法,此时修复代码的最简单方法是:

yield from explore(path)

迭代器不能像那样递归地工作。你必须通过替换

explore(path)

有点像

for value in explore(path):
    yield value

Python 3.3添加了PEP 380中建议的语法yield from X,以达到此目的。你可以用它来代替:

yield from explore(path)

如果使用generators as coroutines,则此语法还支持使用^{}将值传递回递归调用的生成器。上面的简单for循环不会。

相关问题 更多 >