以下文章来源于数据分析与统计学之美,作者黄伟呢
一、开篇
os库应该是使用频率最高的一个文件处理库,但是不得不说Python中还有几个其它的文件处理库,像shutil库、glob库、pathlib库,它们可以说是相互补充,有着自己好用的方法。黄同学亲切的将它们合称为Python文件处理库的四大天王
。
今天呢,咋们就对这4个库来个深度对比,对比一下好像学习什么都快了。
这里采用文字叙述
为大家讲解这四大模块各自的用法,具体内容会在后面详细介绍。
对于os模块来说,这是大家最熟悉的一个库,功能相对很齐全,主要像以下这些功能:
shutil库,最主要的功能就是提供了对文件/文件夹的复制、移动和删除功能,主要如下:
glob库,提供了更加便捷的用来查找符合特定规则的目录和文件的方法,主要它支持*、**、? 、[ ]这四个通配符。
pathlib库中有一些功能超级棒,其中我最喜欢下面这个功能:
有了上述说明,下面详细为大家介绍4个库它们各自的用法。
# 导入
import os
os.getcwd()
结果如下:
文件和目录
组成的列表;path = r"C:\Users\黄伟\Desktop\publish\os模块\test_os模块"
os.listdir(path)
结果如下:
元组拆包
;path = r"C:\Users\黄伟\Desktop\publish\os模块\test_os模块"
for path,dirs,files in os.walk(path):
print(path)
print(dirs)
print(files)
print("\n")
结果如下:
path1 = 'C:\\Users\\黄伟\\Desktop\\publish\\os模块\\huang_wei'
if os.path.exists(path1):
print("指定文件夹存在")
else:
print("指定文件夹不存在")
结果如下:
os.getcwd()
path1 = os.getcwd()+"\\huang_wei"
os.mkdir(path1)
结果如下:
os.getcwd()
path1 = os.getcwd()+"\\huang_wei"
os.mkdir(path1)
结果如下:
path1 = os.getcwd()+"\\huang_wei"
os.rmdir(path1)
----------------------------------
path2 = os.getcwd()+"\\a\\b\\c"
os.rmdir(path2)
结果如下:
path = os.getcwd()
lis = ["a.jpg","b.jpg","c.jpg"]
for i in lis:
x = os.path.join(path,i)
print(x)
结果如下:
绝对路径
和文件名
2部分;path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.split(path1)
结果如下:
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.dirname(path1)
结果如下:
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.basename(path1)
结果如下:
path = os.getcwd()
file_list = os.listdir()
for file in file_list:
if os.path.isdir(file):
print(file)
结果如下:
path = os.getcwd()
file_list = os.listdir()
for file in file_list:
if os.path.isfile(file):
print(file)
结果如下:
os.path.sep
结果如下:
os.path.getsize("我创建的压缩包.zip")
结果如下:
本文所使用的素材,都是基于以下2个文件夹,其中一个文件夹为空。
import shutil
# 1.将a表的“data.txt”移动到b表
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\data.txt"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_b"
shutil.copy(src,dst)
------------------------------------------------------------
# 2.将a表的“data.txt”移动到b表,并重新命名为“new_data.txt”
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\data.txt"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_b\new_data.txt"
shutil.copy(src,dst)
------------------------------------------------------------
# 3.将a表的“data.txt”移动到“不存在”的文件夹
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\data.txt"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_c"
shutil.copy(src,dst)
"""
注意:对于情况3,系统会默认将“test_shutil_c”识别为文件名,而不是按照我们认为的,移动到一个新的不存在的文件夹。
"""
结果如下:
# 将a文件夹移动到b文件夹,由于前面的操作,此时b文件夹中已经有其他文件
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_b"
shutil.copytree(src,dst)
结果如下:
# c文件夹原本是不存在的,我们使用了下方的代码,会自动创建该文件夹
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_c"
shutil.copytree(src,dst)
结果如下:
# 将当前工作目录下的“a.xlsx”文件,移动到a文件夹下
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a"
shutil.move("a.xlsx",dst)
----------------------------------------------------------------
# 将a文件夹下的“a.xlsx”文件,移动到b文件夹中,并重新命名为“aa.xlsx”
src = r"C:/Users/黄伟/Desktop/publish/os模块/test_shutil_a\a.xlsx"
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_b\aa.xlsx"
shutil.move(src,dst)
结果如下:
注意:移动文件夹操作类似,我这里就不赘述了,自行下去学习。
# 将c文件夹彻底删除
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_c"
shutil.rmtree(src)
结果如下:
import zipfile
import os
file_list = os.listdir(os.getcwd())
# 将上述所有文件,进行打包,使用“w”
with zipfile.ZipFile(r"我创建的压缩包.zip", "w") as zipobj:
for file in file_list:
zipobj.write(file)
结果如下:
import zipfile
with zipfile.ZipFile("我创建的压缩包.zip", "r") as zipobj:
print(zipobj.namelist())
结果如下:
import zipfile
# 将压缩包中的“test.ipynb”文件,单独解压到a文件夹下
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a"
with zipfile.ZipFile("我创建的压缩包.zip", "r") as zipobj:
zipobj.extract("test.ipynb",dst)
结果如下:
import zipfile
# 将压缩包中的所有文件,解压到d文件夹下
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_d"
with zipfile.ZipFile("我创建的压缩包.zip", "r") as zipobj:
zipobj.extractall(dst)
结果如下:
使用glob模块能够快速查找我们想要的目录和文件,就是由于它支持*、**
、? 、[ ]这三个通配符,那么它们到底是 什么意思呢?
其实glob库很简单,只有3个主要函数供我们使用,它们分别是glob()、iglob()、escape()函数,因此学习起来特别容易。
“**”
一同使用,默认为False,False表示不递归调用,True表示递归调用;path1 = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\[0-9].png"
glob.glob(path1)
path2 = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\[0-9a-z].*"
glob.glob(path2)
结果如下:
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\[0-9].png"
a = glob.iglob(path1)
for i in a:
print(i)
结果如下:
通过下方两行代码的对比,可以看出escape()函数只是让*
只表示它本来的意思,而不再具有通配符的作用。
glob.glob('t*')
glob.escape('t*')
结果如下:
通过上面的叙述可以知道,glob库其实并没有很多东西,就记住3个通配符
、3个函数
即可。对于我们来说,glob库就是方便我们查找文件而诞生的,因此我们好好掌握glob()这一个函数,其实就够了,其它的知道、会用就行。
在使用之前,需要提前导入pathlib库。
from pathlib import Path
Path对象是这个库的核心,里面有着超级多好用的文件、文件夹
处理方法,供我们调用。
p = Path.cwd()
p
结果如下:
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p
结果如下:
从上图可以看出,Path对象既可以是一个文件对象
,也可以是一个文件夹对象
。根据不同的对象,调用对应的方法,就可以很便捷的处理文件或文件夹。
我们既然针对某个文件操作,所以首先应该获取到文件的Path对象。
p = Path("抽奖.txt")
p.stat()
结果如下:
Path对象,进行路径拼接,直接使用一个/
斜杠即可。
p = Path('C:/Users/Administrator/Desktop/python三剑客')
p1 = p/'pathlib库'
p1
结果如下:
p = Path.cwd()
p.parent
p.parent.parent
结果如下:
我们既然针对某个文件操作,所以首先应该获取到文件的Path对象。
p = Path("抽奖.txt")
p.stat()
结果如下:
以当前工作目录为例:在当前工作目录下,有下方这些文件。
如何获取每个文件对应的路径信息呢?
p = Path.cwd()
for i in p.iterdir():
print(i)
结果如下:
「注意:」 iterdir()方法返回的是直接子文件或子文件夹【不考虑嵌套文件夹中的文件】。
仅想要获取直接子文件的路径信息,使用的是glob()方法。
p = Path.cwd()
file_list = p.glob('*.txt')
for file in file_list:
print(file)
结果如下:
由于需求改变,我不仅想要获取直接子文件的信息,而且还要递归所有文件夹,找到所有符合条件的文件信息?这里有两种办法:
p = Path.cwd()
file_list = p.glob('**/*.txt')
for file in file_list:
print(file)
结果如下:
p = Path.cwd()
file_list = p.rglob('*.txt')
for file in file_list:
print(file)
结果如下:
综上所述:
「一个粉丝留言问我:」 如果你有一个嵌套文件夹,嵌套次数很深。但是我们并不需要一直访问到最后一层,应该怎么办呢?
p = Path.cwd()
file_list = p.rglob('*.txt')
for file in file_list:
print(file)
结果如下:
p = Path.cwd()
file_list = p.rglob('*.txt')
for i,file in enumerate(file_list):
if i <= 2:
print(file)
结果如下:
这个需求很有用,比如我们做文件分类的时候,我们需要创建新的文件夹,用于文件分类。此时,我们需要判断,创建的文件夹是否是不存在的,只有不存在我们才去创建这个文件夹。
p = Path.cwd()
for i in p.iterdir():
print(i)
结果如下:
如果有这么些文件,如何判断文件或文件夹,是否存在呢?
上面我们如果已经判断了不存在666.txt
这个文件,而不存在'b'这个文件夹,现在我们就来创建它。
p = Path.cwd()
p1 = p/'b'
if not Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/b').exists():
p1.mkdir()
结果如下:
上述我们已经为大家创建了单个文件夹,现在我们来创建一个递归文件夹,这里一定要使用parents=True
参数。
p = Path.cwd()
p1 = p/'嵌套第一层'/'嵌套第二层'
p1.mkdir(parents=True)
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p.is_dir()
p.is_file()
结果如下:
p = Path('3.gif')
p.rename("重命名_3.gif")
这个功能真的很赞,超级好用。
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p.name
p.suffix
结果如下:
我们要注意一点,os库
、shutil库
、glob库
是互补的,我们要善于发挥各自的优势,充分利用它们的优势,帮助我们快速的操作文件和文件夹。