Python中os+glob文件操作
在常见的工程中常常会遇见一些需要使用os对文件夹进行操作的时候,本文是记录下常见的os库的使用,以及提供一些自用的代码模块,例如获取文件夹目录下的文件名列表(指定后缀的文件),对路径名进行解析等等操作。
os常见用法
1、os.system(command)
用于启用系统中其他程序
os.system(r'错误报告.txt')
2、os.getcwd()
获取当前程序的路径,常用于和其他的os.path字库的函数来生成完整的路径
os.getcwd()
'c:\\Users\\CircleWang\\Desktop'
3、os.walk(path, topdown=True)
该函数会遍历路径下的文件,并返回一个三元组(root,dirs,files)的迭代器(需要利用for,或者next()才能提取出里面的元组)[注意会遍历所有的子文件夹]。参数path为你所要遍历的目录的地址,参数topdown为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录(默认为开启)
- root(str)是当前遍历的路径名,
- dirs(list)是该path中所有的文件夹的名字(不包括子目录),
- files (list)是该path中所有的文件的名字(包括后缀)(不包括子目录)
for root, dirs, files in os.walk(r'测试', topdown=True): print(root) print(dirs) print(files) print('=================')
测试 ['文件夹A', '文件夹B'] ['文件1.py', '文件2.py'] ================= 测试\文件夹A ['文件夹A的文件夹'] ['子文件夹A的文件1.py', '子文件夹A的文件2.py'] ================= 测试\文件夹A\文件夹A的文件夹 [] [] ================= 测试\文件夹B [] ['子文件夹B的文件1.py'] =================
以上是一个例子,大家可以看到这个遍历类似于二叉树的深度优先遍历,会一直遍历到你的子文件夹为空的时候。但是如果我只想遍历一层怎么办呢?我们可以采用next(iter)的方式来逐层迭代,记住顺序是深层遍历的顺序。
path_iter = os.walk(r'测试', topdown=True)
next(path_iter)
('测试', ['文件夹A', '文件夹B'], ['图片1.jpg', '图片2.jpg', '图片3.jpg', '文件1.py', '文件2.py'])
next(path_iter)
('测试\\文件夹A',
['文件夹A的文件夹'],
['子文件夹A的文件1.py',
'子文件夹A的文件2.py',
'文件夹A的图片1.jpg',
'文件夹A的图片2.jpg',
'文件夹A的图片3.jpg'])
next(path_iter)
('测试\\文件夹A\\文件夹A的文件夹', [], [])
next(path_iter)
('测试\\文件夹B', [], ['子文件夹B的文件1.py'])
4、 os.listdir(path)
这一个就是获得指定目录下的所有文件(或者文件夹)的名字(包括有后缀),这一个函数主要适用于path里文件比较干净,我们只想提取出这些文件的文件名加以处理。常常会通过.split('.')[0]来去除后缀名。
5、os.mkdir(path)
创建一个路径为path的文件夹。主要该path是目录路径不是文件路径,并且path的上一级目录必须存在,换句话说os.mkdir只能创建单层文件夹。如果当父目录不存在的时候你也想创建,可以使用os.makedirs(path),这样会就算父目录不存在也能创建。
os.path子库的常见用法
1、os.path.abspath(path)
返回文件的绝对路径。说得更直观点就是返回:“当前的工作路径”+path,而并不会关心这个文件是否存在。其实这个函数就干了一件事就是把当前的工作路径组合上你输入的字符串。因此我们想要返回出我们需要的文件的完整路径,其实这里的path我们应该是填写目标文件相对于当前程序的”相对路径“才行。
import os
os.getcwd()
'c:\\Users\\CircleWang\\Desktop\\Python'
os.path.abspath("我不存在.txt")
'c:\\Users\\CircleWang\\Desktop\\Python\\我不存在.txt'
其实大家可以看到这里的文件”我不存在.txt“是并没有这个文件(无论在哪)。还有一些小函数技巧。
- 返回当前目录的绝对路径:
os.path.abspath(r".")
'c:\\Users\\CircleWang\\Desktop\\Python'
- 返回上层目录的绝对路径
os.path.abspath(r"..")
'c:\\Users\\CircleWang\\Desktop'
2、os.path.dirname(path)
有的时候我们需要获取的是文件所在的目录名称,这个时候我们可以使用dirname来获取。
import os
path = r'C:\Users\CircleWang\Desktop\Python\Python基础笔记.docx'
os.path.dirname(path)
'C:\\Users\\CircleWang\\Desktop\\Python'
需要注意的是:这个函数和os.path.abspath(path)一样,这个文件不一定存在,只要是给的是一个路径的格式那么就会得到目录。
3、os.path.basename(path)
这个函数与上一个函数dirname相反,这个函数是获取文件名(包括有后缀),还是一样的,这个文件不一定是存在的(换句话说这些个函数都只是对字符串解析,并不涉及到判定文件存不存在)。
import os
path = r'C:\Users\CircleWang\Desktop\Python\测试。txt'
os.path.basename(path)
'测试。txt'
这里我故意打的是。txt,就是想说明这个函数只是在处理字符串而已(识别到\的最后一部分,然后提取出来)
4、os.path.join(path, *paths)
这个函数是我们常用的最多的函数,用于将两个路径进行连接,比如我已经知道了一个文件夹,想要读取里面所有的文件,那么我就需要知道里面所有文件的完整路径,就可以用这个函数来遍历文件名生成完整路径。
os.path.join('c:\\Users\\Desktop\\Python', '我的文件夹/我的文件名')
'c:\\Users\\Desktop\\Python\\我的文件夹/我的文件名'
os.path.join('c:\\Users\\Desktop\\Python', '我的文件夹','我的文件名')
'c:\\Users\\Desktop\\Python\\我的文件夹\\我的文件名'
大家可以看到,其实这个连接函数就在不同的path之间加入了‘\\’而已,也不会验证你的整个路径是否正确(上述第一个例子中第二个字符串里我就故意写成了‘我的文件夹/我的文件名’,生成的路径显然是有问题的)。
5、os.path.exists(path)
用于判断文件,或者文件夹是否存在,如果存在则该函数将会返回True,否则返回Fasle。一般情况会和os.mkdir(path)来一起使用,先判断是否存在该文件夹,如果不存在则创,见代码。
root = './WYQ'
if not os.path.exists(os.path.join(root,'temp')):
os.mkdir(os.path.join(root,'temp'))
不过需要提醒的是,这个os.mkdir只能创建单层文件夹,换句话说你需要保证root目录存在。
glob库的操作
可以查找符合特定规则的文件路径名。
1、glob.glob(path)
返回所有匹配的文件路径列表。主要是使用正则表达式来得到指定路径下的,指定后缀的文件完整路径列表。其实这个和os.walk很像,但是walk的功能太强大了,会一直遍历到很深的程度,有时候我们就是只想要获取当前层次的文件下的文件。此时就可以采用glob.glob。以下作为一个例子。
glob.glob('C:/Users/CircleWang/Desktop/Python/测试/*')
['C:/Users/CircleWang/Desktop/Python/测试\\图片1.jpg',
'C:/Users/CircleWang/Desktop/Python/测试\\文件1.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件2.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件夹A',
'C:/Users/CircleWang/Desktop/Python/测试\\文件夹B']
glob.glob('C:/Users/CircleWang/Desktop/Python/测试/*/*')
['C:/Users/CircleWang/Desktop/Python/测试\\文件夹A\\子文件夹A的文件1.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件夹A\\子文件夹A的文件2.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件夹A\\文件夹A的文件夹',
'C:/Users/CircleWang/Desktop/Python/测试\\文件夹B\\子文件夹B的文件1.py']
glob.glob('C:/Users/CircleWang/Desktop/Python/测试/*.py')
['C:/Users/CircleWang/Desktop/Python/测试\\文件1.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件2.py']
# 查找文件只用到三个匹配符:"*", "?", "[]"。
# "?"匹配单个字符;
# "[]"匹配指定范围内的字符,如:[0-9]匹配数字。注意无论[]里面写什么,都只会匹配单个
# "*"匹配任意
glob.glob(r'C:/Users/CircleWang/Desktop/Python/测试/*.[pj]*') # 这个意思是匹配 "任意字符.[该位置未p或者j]任意值符“ 由于.jpg和.py是符合这个条件的因此读取出来了,千万不能以为可以用[py,jpg]来匹配。
['C:/Users/CircleWang/Desktop/Python/测试\\图片1.jpg',
'C:/Users/CircleWang/Desktop/Python/测试\\文件1.py',
'C:/Users/CircleWang/Desktop/Python/测试\\文件2.py']
其实最后一个例子就是我们常用的,获取指定后缀名(中括号里可以写多个)的文件路径列表。常用正则表达式也写在了上面。
特定后缀文件获取
以这个文件夹作为例子,编写一些获取指定后缀文件名的脚本。
imgset_files = ['C:\\Users\\CircleWang\\Desktop\\Python\\测试',]
# 如果glob.glob传入的路径不包括正则表达符号,就只会返回该路径
glob.glob(os.path.join(imgset_files[0]))
['C:\\Users\\CircleWang\\Desktop\\Python\\测试']
imgset_files = ['C:\\Users\\CircleWang\\Desktop\\Python\\测试',]
# 如果glob.glob传入的路径不包括正则表达符号,就只会返回该路径
glob.glob(os.path.join(imgset_files[0]))
['C:\\Users\\CircleWang\\Desktop\\Python\\测试']
glob.glob(os.path.join(imgset_files[0], '*.jpg'))
['C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片1.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片2.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片3.jpg']
glob.glob(os.path.join(imgset_files[0], '*.py'))
['C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件1.py',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件2.py']
如果图片处在不同的文件夹里面,我们可以将图片的上层目录放在imgset_files列表中,然后循环列表,并把得到的文件路径列表进行合并就好了。
imgset_files = ['C:\\Users\\CircleWang\\Desktop\\Python\\测试', 'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件夹A']
img_path_list = [] # 用于储存最后的图片地址的列表
for imgset_file_name in imgset_files:
img_path_list = glob.glob(os.path.join(imgset_file_name, '*.jpg')) + img_path_list
print(img_path_list)
['C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件夹A\\文件夹A的图片1.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件夹A\\文件夹A的图片2.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\文件夹A\\文件夹A的图片3.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片1.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片2.jpg',
'C:\\Users\\CircleWang\\Desktop\\Python\\测试\\图片3.jpg']