Python Cookbook-2.16 遍历目录树

任务

需要检查一个“目录”,或者某个包含子目录的目录树,并根据某种模式迭代所有的文件(也可能包含子目录)。

解决方案

Python 标准库模块 os中的生成器(generator)os.walk对于这个任务来说完全够用了不过我们可以给它打扮打扮,将其封装为一个我们自己的函数:

import os,fnmatch
def all_files(root, patterns = '*',single_level = False, yield_folders = False):
#将模式从字符串中取出放入列表中
	patterns = patterns.split(;)
	for path,subdirs,files in os.walk(root):
		if yield_folders:
			files.extend(subdirs)
		files.sort()
		for name in files:
			for pattern in patterns:
				if fnmatch.fnmatch(name,pattern):
					yield os.path.join(path,name)
					break
		if single_level:
			break

讨论

标准文件树遍历生成器 os.walk 既强大又简单灵活。不过,os.walk 还缺乏应用程序需要的一些细节上的处理能力,比如根据某种模式选择文件,扁平(线性)地以排序后的顺序循环所有文件(也可能包括子目录),检查一个单一目录(不进入其子目录)。本节代码则展示了,通过将 os.walk 封装到另一个简单的生成器中,并使用标准库模块fnmatch 来检查文件名匹配模式,是多么的简单方便。

文件名匹配模式可能是大小写无关的(这依赖于平台),也可能是相关的,比如UNIX风格,不过这些能力都是标准 fmatch 模块能够提供的。为了指定多个模式,可用分号将它们连接起来。注意,这意味着那些分号本身不是模式的一部分。举个例子,可以很容易地从/tmp目录及其子目录中获得一个包括所有 Python 和 HTML文件的列表:

thefiles = list(all_files('/tmp','*.py;*.htm;*.html'))

如果想一次处理一个文件的路径(比如,逐行打印它们),不需要先建立一个列表:可以直接对 all fles 调用的结果进行循环操作:

for path in all_files('/tmp',*.py;*.htm;*.html'):
	print path

如果你的平台是大小写敏感的,而且你也希望严格匹配大小写,那么需要在指定模式的时候稍微辛苦点,比如,用“.[Hh][Tt][Mm][Ll]”来替代原来的“.html”。

你可能感兴趣的:(#Python学习,python,开发语言)