在Python中,如何找到一个目录下的所有文件,包括子目录中的文件?

5

是否有内置函数可以查找特定目录下的所有文件,包括子目录中的文件? 我尝试了这段代码,但它不起作用...也许逻辑本身就是错误的...

def fun(mydir):
    lis=glob.glob(mydir)
    length=len(lis)
    l,i=0,0
    if len(lis):
        while(l+i<length):
            if os.path.isfile(lis[i]):
                final.append(lis[i])
                lis.pop(i)
                l=l+1
                i=i+1
            else:
                i=i+1
            print final
        fun(lis)
    else:
        print final
3个回答

14

没有内置的函数,但使用os.walk,可以很容易构建它:


import os
def recursive_file_gen(mydir):
    for root, dirs, files in os.walk(mydir):
        for file in files:
            yield os.path.join(root, file)

ETA: os.walk函数可以递归地遍历目录树;recursive_file_gen函数是一个生成器(使用yield关键字来生成下一个文件)。要获取结果列表,请执行以下操作:

list(recursive_file_gen(mydir))

@pythbegin: 添加了解释,请问如有任何不清楚的具体点,请提出。 - SilentGhost
@pyth:在Python文档中有一个正式的定义 - SilentGhost
我对你的代码进行了一些更改,现在它是这样的: def listall(parent): lis=[] for root, dirs, files in os.walk(parent): for name in files: if os.path.getsize(os.path.join(root,name))>500000: lis.append(os.path.join(root,name)) return lis我的目标是找到所有大小大于500000的文件...它正常工作... 但是当我在Windows上的“临时互联网文件”文件夹中使用此函数时,我遇到了这个错误... 我认为这是因为文件名中有特殊字符。 你能提供一些建议吗? - pythBegin
抱歉...我忘了提到错误 Traceback (most recent call last): File "<pyshell#4>", line 1, in <module> listall(a) File "<pyshell#2>", line 5, in listall if os.path.getsize(os.path.join(root,name))>500000: File "C:\Python26\lib\genericpath.py", line 49, in getsize return os.stat(filename).st_size WindowsError: [Error 123] 文件名、目录名或卷标语法不正确: 'C:\Documents and Settings\khedarnatha\Local Settings\Temporary Internet Files\Content.IE5\EDS8C2V7\??????+1[1].jpg' 就是这样 - pythBegin
@pyth: 我怀疑这与文件名的编码有关。很难说,因为您没有提供文件名的示例。显然,?不能出现在文件名中,因为它是无效的。尝试查看文件的实际名称。os.walk返回了什么,os.path.join返回了什么。我建议您提出单独的问题,因为这超出了此问题的范围。 - SilentGhost
不建议使用“_file_”作为变量名,因为它会遮蔽内置名称“_file_”。但在这种情况下,没有任何区别。使用了你的代码片段!谢谢。+1 - Qlimax

3
我强烈推荐Jason Orendorff编写的这个路径模块: http://pypi.python.org/pypi/path.py/2.2 不幸的是,他的网站现在已经关闭,但您仍然可以从上面的链接(或通过 easy_install ,如果您喜欢)下载。
使用这个路径模块,您可以对路径执行各种操作,包括您请求的文件遍历。以下是一个示例:
from path import path

my_path = path('.')

for file in my_path.walkfiles():
    print file

for file in my_path.walkfiles('*.pdf'):
    print file

此外,还有许多与路径相关的方便函数:

In [1]: from path import path

In [2]: my_dir = path('my_dir')

In [3]: my_file = path('readme.txt')

In [5]: print my_dir / my_file
my_dir/readme.txt

In [6]: joined_path = my_dir / my_file

In [7]: print joined_path
my_dir/readme.txt

In [8]: print joined_path.parent
my_dir

In [9]: print joined_path.name
readme.txt

In [10]: print joined_path.namebase
readme

In [11]: print joined_path.ext
.txt

In [12]: joined_path.copy('some_output_path.txt')

In [13]: print path('some_output_path.txt').isfile()
True

In [14]: print path('some_output_path.txt').isdir()
False

还有更多的操作可以执行,但这些是我经常使用的一些操作。请注意,path类继承自string,因此它可以在任何可以使用string的地方使用。另外,请注意,通过使用重载的/运算符,两个或多个path对象可以轻松地连接在一起。

希望这可以帮助你!


2

你需要的是os.walk()。

但为了提高性能,尝试使用软件包scandir。它也是Python 3.5标准库的一部分,并在PEP471中有描述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接