在windows平台下用Python做工程的时候,经遇到需要对某类文件生成路径的情况,此时常用的方法是在cmd命令行中去dir。但是这样会生成一个文件。例如列出所有C盘中jpg图像的路径,在cmd中输入dir C:\*.jpg /s/b > list.txt,或者在python程序中os.system(dir C:\*.jpg /s/b > list.txt)。这样会生成一个list.txt的文件,在我们的工程中,又要去读取这个文件,这样虽然很方便,但是很low。更有强迫症同学反映,每次都要os.remove('list.txt')。这里教大家一种更为方便的方法。调用os.path.walk。但是这个函数在Py3.x就没了,因为Py2.x就有os.walk,而且更好用,所以Py3.x只有os.walk。
先说os.path.walk(top, func, arg). top是要操作的起始路径,根据上文则为'C:\\';func是一个自定义的函数,此函数必须传入,并且有三个参数func(arg, top, names),func中的arg就是walk中的arg,func中top是现在操作到的文件路径,不一定为walk中的top,names为func中top文件路径下的所有文件和文件夹名称;arg为用户传入的参数。再看看walk的定义吧:
<span style="font-size:18px;">def walk(top, func, arg):
warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",stacklevel=2)
try:
names = os.listdir(top)
except os.error:
return
func(arg, top, names) #这里体现了用户想要的操作
for name in names:
name = join(top, name) #因为此定义同在ntpath.py中,所以join是指os.path.join
if isdir(name): #同理,isdir指os.path.isdir
walk(name, func, arg)</span>
根据以上代码,写出一个获取绝对路径的代码,一个获取相对路劲的代码
<span style="font-size:18px;">def absfunc(arg, top, names):
for name in names:
if name.endswith(".jpg"):
arg.append(os.path.join(top, name))</span>
<span style="font-size:18px;">def relfunc(arg, top, names):
for name in names:
if name.endswidth(".jpg"):
arg.append(name)</span>
在使用时:
<span style="font-size:18px;">abspath = []
relpath = []
os.path.walk("C:\\",absfunc,abspath)
os.path.walk("C:\\",relfunc,relpath)</span>
则abspath存储了C:\*.jpg的绝对路径,relpath存储了C:\*.jpg的文件名
再来说说os.walk(top, topdown=True, οnerrοr=None, followlinks=False)函数。看着参数很多,其实默认参数可以不理。top是要操作的起始文件,topdown:true先返回文件夹下的文件,再遍历文件夹中的目录,false先遍历文件夹中中的目录,再返回文件夹中的文件。os.walk不像os.path.walk那样需要用户定义函数才能用,而是返回生成器,包含三个元素,分别表示分别表示每次遍历的路径名root,目录列表dir和文件列表names。对于os.walk的编程如下。
<span style="font-size:18px;">abspath = []
relpath = []
for root,dir,names in os.walk("C:\\"):
for name in names:
if name.endswith('.jpg'):
abspath.append(os.path.join(root,name))
relpath.append(name)</span>
可以看到,os.walk函数比os.path.walk简单。而且,os.walk函数本身不会在names中返回root文件夹中的目录,而是将目录返回在dir中,names中的肯定是文件。而os.path.walk将两这不予区分的返回在names中。
PS:
glob库同样提供了类似的功能,但是功能有限。
glob.glob(search_path) #返回查找结果的列表
glob.iglob(search_path) #返回查找结果的可迭代对象
用法类似Windows中的查找。"*"匹配0~多个字符;"?"匹配单个字符;"[]"匹配指定范围内的字符,如:[0-9]匹配数字
abspath = glob.glob("C:\\*.jpg"),但是glob函数只会列出指定目录中的查找对象,不会遍历指定目录中的目录。glob.iglob()函数则返回该列表的可迭代对象