【问题标题】:Traversing Directories遍历目录
【发布时间】:2016-07-24 18:02:10
【问题描述】:

我正在尝试编写一个 python 程序,它接受一个输入目录,并打印出该目录中的所有 .txt 文件。但是,如果其中有另一个文件夹,它必须使用递归来做同样的事情。

我的问题是只有 .txt 文件,并没有进一步遍历目录。

import os
path = input("What directory would you like to search?: ")
def traverse(path):
    files = os.listdir(path)
    for i in files:
        if os.path.isdir(i) == True:
            traverse(i)
        elif i.endswith('.txt'):
            print(i)
traverse(path)

有什么问题?

【问题讨论】:

  • 必须使用递归吗? os.walk() 会更容易。

标签: python python-2.7 python-3.x module


【解决方案1】:

看起来你的代码失败的原因是因为if os.path.isdir(i) == True 行总是失败,不管文件是否是目录。这是因为files变量存储的是相对路径而不是绝对路径,导致检查失败。

如果您想使用您提供的递归方法来执行此操作,您的代码可以更改如下:

import os
path = input("What directory would you like to search?: ")
def traverse(path):
    files = os.listdir(path)
    files = (os.path.join(os.path.abspath(path), file) for file in files)
    for i in files:
        if os.path.isdir(i) == True:
            traverse(i)
        elif i.endswith('.txt'):
            print(i)
traverse(path)

这是使用 fnmatch 的一种更好的方法(适用于 Use a Glob() to find files recursively in Python? 中的其余代码)。它将递归搜索提供的目录中的所有文件,并匹配以

结尾的文件
import fnmatch
import os

path = input("What directory would you like to search?: ")

def traverse(path):
    matches = []
    for root, dirnames, filenames in os.walk(path):
        for filename in fnmatch.filter(filenames, '*.txt'):
            matches.append(os.path.join(root, filename))
    print matches

traverse(path)

【讨论】:

  • 有没有办法通过递归而不是 fnmatch 模块来做到这一点?
  • 只有一个建议。返回一个生成器 exp 或 yield filename 而不是返回一个列表,这对于一个大目录来说是相当大的。否则很好。
【解决方案2】:

您缺少完整路径,否则没关系。见下文

def traverse(path):
    files = os.listdir(path)
    for i in files:
        if os.path.isdir(os.path.join(path,i)):
            traverse(os.path.join(path,i))
        elif i.endswith('.txt'):
            print(os.path.join(path,i))

【讨论】: