用os.listdir(path)可查询path目录下的所有文件,用os.walk(path)可查询path目录及其子目录下的所有文件。
但是os.walk()不能控制遍历文件树的深度,而且默认会忽略发生的异常,把没有访问权限的目录直接判定为空目录。如下:
>>> import os
>>> os.listdir("/root") # 使用os.listdir()查询,遇到异常会直接抛出
Traceback (most recent call last):
File "" , line 1, in <module>
PermissionError: [Errno 13] Permission denied: '/root'
>>> list(os.walk("/root")) # os.walk()默认会忽略发生的异常
[]
>>> list(os.walk("/root", onerror=print)) # 可传入onerror参数,记录发生的异常
[Errno 13] Permission denied: '/root'
[]
基于os.walk()自定义一个函数:每次迭代时遍历一个子目录。
采用生成器模式,可以让程序一边遍历文件,一边进行处理。
def find_all_files(path: str = '.', onerror=print):
"""
查找`path`目录及其子目录下的所有文件,返回一个生成器。
- `path`: 一个已存在的目录。
- `onerror`: 记录异常的函数名。
"""
for basepath, dirnames, filenames in os.walk(path, onerror=onerror):
paths = []
for i in dirnames + filenames:
paths.append(os.path.join(basepath, i))
yield paths
if __name__ == "__main__":
for paths in find_all_files("."):
print(paths)
基于os.listdir()自定义一个函数:在指定目录下递归遍历某种后缀名的文件,返回这些文件的绝对地址列表。
为了更好的模块化、与外部解耦,加入了多个输入、以及检查输入的语句和日志语句,代码变得臃肿了。
import os
def searchFile(path, suffix=None, depth=-1):
"""
在目录`path`下检索所有文件,把符合要求的文件名的绝对地址保存成一个list返回。
如果检索结果为空,则返回值为 [ ] 。
`path` : 一个在系统中存在的目录名
`suffix` : 文件的后缀名,区分大小写,可以是一个字符串或字符串的元组。默认不区分后缀名
`depth` : 最多检索depth层子目录。depth为负数时检索无限层
"""
if not os.path.isdir(path):
raise ValueError("'path' must be an existing directory.")
def __searchFile(path, suffix, depth):
try:
dir_list = os.listdir(path)
# 可能会遇到没有访问权限的文件夹,这里把异常处理掉,以免打断程序运行
except PermissionError as e:
print("PermissionError: {}".format(e))
return -1 # 退出函数,不检索该目录
file_list = []
for name in dir_list:
# 把目录名和文件名合成一个子路径
sub_path = os.path.join(path, name)
# 如果子路径是一个文件夹且depth!=0,就递归调用本函数进入该文件夹检索,即深度优先搜索
if depth != 0 and os.path.isdir(sub_path) == True:
sub_list = __searchFile(sub_path, suffix, depth-1)
if sub_list != -1:
file_list.extend(sub_list)
# 如果子路径是一个文件,就判断后缀名是否正确,如果没输入suffix就不考虑后缀名
elif suffix == None or sub_path.endswith(suffix):
file_list.append(sub_path)
print(sub_path) # 这行只是实时显示,可以注释掉
return file_list
return __searchFile(path, suffix, depth)
if __name__ == "__main__":
searchFile("D:\\", ".txt")