Python的几种文件遍历方式
本次列举python的几种不同的文件遍历方式。
运行环境
原始文件目录结构
E:
|-files
|-.git
|-config
|-HEAD
|-index
|-hooks
|-applypatch-msg.sample
|-commit-msg.sample
|.vscode
|-launch.json
|-tasks.json
|-src
|-helloworld.h
|-helloworld.cpp
|-main.cpp
glob 库
注意: 本方式无法遍历指令目录下以点号"."开头的文件夹,比如".git" ".vs"
glob模块是最简单的模块之一,内容非常少。用它可以查找符合特定规则的文件路径名。跟使用windows下的文件搜索差不多。查找文件只用到三个匹配符:"*", "?", "[]"
"*"匹配0个或多个字符;
"?"匹配单个字符;
"[]"匹配指定范围内的字符,如:[0-9]匹配数字。
glob.glob 方式
函数定义: def glob(pathname, *, recursive=False):
函数功能: 匹配所有的符合条件的文件,并将其以list的形式返回
参数说明: 它只有一个参数pathname,定义了文件路径匹配规则,这里可以是绝对路径,也可以是相对路径。
下面是使用glob.glob的例子:
遍历指定目录下的所有文件,不包括子文件
import os
import glob
def func1():
for strFile in glob.glob(r'E:\files\*', recursive=True):
print('%s : "%s"' % (("file" if os.path.isfile(strFile) else "dir "), strFile))
if __name__ == '__main__':
func1()
# 输出为:
# file : "E:\files\main.cpp"
# dir : "E:\files\src"
遍历指定目录下的所有文件,包括子文件
import os
import glob
def func1():
for strFile in glob.glob(r'E:\files\**', recursive=True):
print('%s : "%s"' % (("file" if os.path.isfile(strFile) else "dir "), strFile))
if __name__ == '__main__':
func1()
# 输出为:
# dir : "E:\files\"
# file : "E:\files\main.cpp"
# dir : "E:\files\src"
# file : "E:\files\src\helloworld.cpp"
# file : "E:\files\src\helloworld.h"
获取指定目录下的所有cpp文件
import os
import glob
def func1():
for strFile in glob.glob(r'E:\files\*\*.cpp', recursive=True):
print('%s : "%s"' % (("file" if os.path.isfile(strFile) else "dir "), strFile))
if __name__ == '__main__':
func1()
# 输出为:
# file :"E:\files\src\helloworld.cpp"
glob.iglob 方式
函数定义: def iglob(pathname, *, recursive=False):
函数功能: 获取一个可遍历对象,使用它可以逐个获取匹配的文件路径名。
与glob.glob()的区别是:glob.glob同时获取所有的匹配路径,而glob.iglob一次只获取一个匹配路径,相当于迭代器。查看glob.glob()方法的源码可获知两者的关系。
def glob(pathname, *, recursive=False):
return list(iglob(pathname, recursive=recursive))
下面是一个简单的例子:
import glob
#父目录中的.py文件
f = glob.iglob(r'../*.py')
print (f) #<generator object iglob at 0x00B9FF80>
for py in f:
print (py)
pathlib库
Path(‘dir’).rglob(“pattern”) 递归方式
函数定义: def rglob(self, pattern):
函数功能:
Recursively yield all existing files (of any kind, including directories) matching the given relative pattern, anywhere in this subtree.
递归遍历指定目录下的所有文件
import os
from pathlib import Path
def func2():
path = Path(r'E:\files')
for p in path.rglob("*"):
print('%s : "%s"' % (("file" if os.path.isfile(str(p)) else "dir "), str(p)))
if __name__ == '__main__':
func2()
# 输出为:
# dir : "E:\files\.git"
# dir : "E:\files\.vscode"
# file : "E:\files\main.cpp"
# dir : "E:\files\src"
# file : "E:\files\.git\config"
# file : "E:\files\.git\HEAD"
# dir : "E:\files\.git\hooks"
# file : "E:\files\.git\index"
# file : "E:\files\.git\hooks\applypatch-msg.sample"
# file : "E:\files\.git\hooks\commit-msg.sample"
# file : "E:\files\.vscode\launch.json"
# file : "E:\files\.vscode\tasks.json"
# file : "E:\files\src\helloworld.cpp"
# file : "E:\files\src\helloworld.h"
递归遍历指定目录下的所有cpp文件
import os
from pathlib import Path
def func2():
path = Path(r'E:\files')
for p in path.rglob("*.cpp"):
print('%s : "%s"' % (("file" if os.path.isfile(str(p)) else "dir "), str(p)))
if __name__ == '__main__':
func2()
# 输出
# file : "E:\files\main.cpp"
# file : "E:\files\src\helloworld.cpp"
Path(‘dir’).glob(“pattern”) 非递归方式
函数定义: def glob(self, pattern):
函数功能:
Iterate over this subtree and yield all existing files (of any kind, including directories) matching the given relative pattern.
非递归遍历指定目录下的所有文件
import os
from pathlib import Path
def func2():
path = Path(r'E:\files')
for p in path.glob("*"):
print('%s : "%s"' % (("file" if os.path.isfile(str(p)) else "dir "), str(p)))
if __name__ == '__main__':
func2()
# 输出
# dir : "E:\files\.git"
# dir : "E:\files\.vscode"
# file : "E:\files\main.cpp"
# dir : "E:\files\src"
非递归遍历指定目录下的所有cpp文件
import os
from pathlib import Path
def func2():
path = Path(r'E:\files')
for p in path.glob("*.cpp"):
print('%s : "%s"' % (("file" if os.path.isfile(str(p)) else "dir "), str(p)))
if __name__ == '__main__':
func2()
# 输出
# file : "E:\files\main.cpp"
os.walk方式
函数定义: def walk(top, topdown=True, onerror=None, followlinks=False):
函数功能: 遍历目录,topdown=false表示先返回目录,后返回文件
参数说明:
top:表示需要遍历的目录树的路径。
topdown: topdown的默认值是True,表示首先返回根目录树下的文件,然后遍历目录树下的子目录。值设为False时,则表示先遍历目录树下的子目录,返回子目录下的文件,最后返回根目录下的文件。
onerror: onerror的默认值是None,表示忽略文件遍历时产生的错误。如果不为空,则提供一个自定义函数提示错误信息后继续遍历或抛出异常中止遍历。
该函数返回一个列表,列表中的每一个元素都是一个元组,该元组有3个元素,分别表示每次遍历的路径名,目录列表和文件列表。
followlinks: 默认情况下,os.walk 不会遍历软链接指向的子目录,若有需要请将followlinks设定为true
该函数返回一个列表,列表中的每一个元素都是一个元组,该元组有3个元素,分别表示每次遍历的路径名,目录列表和文件列表。
>>> r=os.walk('d:\\test2',topdown=False)
>>> r
<generator object walk at 0x0000000004C5D480>
>>> list(r)
[('d:\\test2\\dir1', [], []), ('d:\\test2\\dir2\\dir3', [], ['2.txt', '33.bmp']), ('d:\\test2\\dir2', ['dir3'], ['1.txt']), ('d:\\test2', ['dir1', 'dir2'], [])]
用root,dirs,files三个变量遍历目录的的目录层级,目录层级的子目录,目录层级下的文件
for root,dirs,files in os.walk(r'd:\\test2',topdown=False):
root:表示当前遍历到哪一级目录了,目录的名字是谁
dirs:表示root下有哪些子目录
files:表示root下边有几个文件
遍历某一文件下的所有文件,首先返回根目录树下的文件,然后遍历目录树下的子目录
import os
def func3():
for root, dirs, files in os.walk(r'E:\files', topdown=True):
for name in files:
print('file : ' + os.path.join(root, name))
for name in dirs:
print('dir : ' + os.path.join(root, name))
if __name__ == '__main__':
func3()
# 输出
# file : E:\files\main.cpp
# dir : E:\files\.git
# dir : E:\files\.vscode
# dir : E:\files\src
# file : E:\files\.git\config
# file : E:\files\.git\HEAD
# file : E:\files\.git\index
# dir : E:\files\.git\hooks
# file : E:\files\.git\hooks\applypatch-msg.sample
# file : E:\files\.git\hooks\commit-msg.sample
# file : E:\files\.vscode\launch.json
# file : E:\files\.vscode\tasks.json
# file : E:\files\src\helloworld.cpp
# file : E:\files\src\helloworld.h
遍历某一文件下的所有文件,先遍历目录树下的子目录,返回子目录下的文件
import os
def func3():
for root, dirs, files in os.walk(r'E:\files', topdown=False):
for name in files:
print('file:' + os.path.join(root, name))
for name in dirs:
print('dir:' + os.path.join(root, name))
if __name__ == '__main__':
func3()
# 输出
# file : E:\files\.git\hooks\applypatch-msg.sample
# file : E:\files\.git\hooks\commit-msg.sample
# file : E:\files\.git\config
# file : E:\files\.git\HEAD
# file : E:\files\.git\index
# dir : E:\files\.git\hooks
# file : E:\files\.vscode\launch.json
# file : E:\files\.vscode\tasks.json
# file : E:\files\src\helloworld.cpp
# file : E:\files\src\helloworld.h
# file : E:\files\main.cpp
# dir : E:\files\.git
# dir : E:\files\.vscode
# dir : E:\files\src
从以上例子可以看出,topdown设值不同,os.walk()返回的列表元素顺序不同(但不是相反),所以遍历后的结果也不同。