【问题标题】:Error on os.walk – I need the result for the specified directory onlyos.walk 上的错误 – 我只需要指定目录的结果
【发布时间】:2017-04-21 00:08:04
【问题描述】:

这是一个演示,什么对我有用,什么对我没用:

import os
path2   = 'D:\\'

# this works
for curdir, dirlist, flist in os.walk(path2):
    pass

# this fails
curdir, dirlist, flist = os.walk(path2)

【问题讨论】:

  • 你为什么认为失败的那个应该起作用?
  • os.walk 产生零个或多个三元组。分配将失败,要么解包的值太少,要么解包的值太多。除非它恰好产生 3 次。即使在这种情况下,结果也不会是您所期望的。

标签: python


【解决方案1】:

问题是os.walk() 返回了一个生成器。这样做:

curdir, dirlist, flist = os.walk(path2)

可能有效,也可能无效。

首先让我们考虑一下:

for curdir, dirlist, flist in os.walk(path2):
    pass

这与将os.walk() 返回的生成器分配给一个名称并在其上不断调用next() 直到引发StopIteration 基本相同。

walk = os.walk(path2)

try:
    while True:
        dirpath, dirnames, filenames = next(walk)

        ... do something ...
except StopIteration:
    pass

现在如果我们回到另一个例子:

curdir, dirlist, flist = os.walk(path2)

那么上面做的也一样:

walk = os.walk(path2)
curdir = next(walk)
dirlist = next(walk)
flist = next(walk)

如果生成器产生 3 个或更多值,则不会失败。但是,如果它产生的值少于 3 个,那么它将失败,因为要解包的值少于 3 个。

所以如果os.walk() 返回的生成器只产生一个值。

curdir, dirlist, flist = os.walk(path2)

那么上面会导致如下错误:

ValueError: 没有足够的值来解包(预期 3,得到 1)

如果是因为你只需要第一个值,那么直接调用next()。但是一定要抓住任何潜在的StopIteration

try:
    curdir, dirlist, flist = next(os.walk(path2))
except StopIteration:
    pass

最后。除非是因为您使用dirlistflist 作为获取给定路径下的目录和文件的简单方法。那么您可能不需要os.walk,而只需使用os.listdiros.scandir

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您想要的不是os.walk,它输出path2 的每个子目录中的文件/目录列表,而是os.scandir,它列出了path2 本身内的所有条目。

    来自上面链接的文档的示例:

    with os.scandir(path) as it:
        for entry in it:
            if not entry.name.startswith('.') and entry.is_file():
                print(entry.name)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2013-11-17
      相关资源
      最近更新 更多