前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度对比Python中4大文件处理库(os、shutil、glob、pathlib)

深度对比Python中4大文件处理库(os、shutil、glob、pathlib)

作者头像
快学Python
发布2021-12-07 14:34:36
6.2K0
发布2021-12-07 14:34:36
举报
文章被收录于专栏:快学Python

一、开篇

os库应该是使用频率最高的一个文件处理库,但是不得不说Python中还有几个其它的文件处理库,像shutil库glob库pathlib库,它们可以说是相互补充,有着自己好用的方法。黄同学亲切的将它们合称为Python文件处理库的四大天王

今天呢,咋们就对这4个库来个深度对比,对比一下好像学习什么都快了。

二、四大库各自好用的地方

这里采用文字叙述为大家讲解这四大模块各自的用法,具体内容会在后面详细介绍。

1. os库

对于os模块来说,这是大家最熟悉的一个库,功能相对很齐全,主要像以下这些功能:

  • os.getcwd():获取当前的工作路径;
  • os.chdir() :改变当前工作目录到指定的路径;
  • os.listdir(path):传入任意一个path路径,返回的是该路径下所有文件和目录组成的列表;
  • os.mkdir():创建文件夹;
2. shutil库

shutil库,最主要的功能就是提供了对文件/文件夹的复制、移动和删除功能,主要如下:

  • shutil.copy(src,dst):复制文件,src表示源文件,dst表示目标文件夹;
  • shutil.copytree(src,dst):复制文件夹,src表示源文件夹,dst表示目标文件夹;
  • shutil.move(src,dst):移动文件/文件夹,src表示源文件/文件夹,dst表示目标文件夹;
  • shutil.rmtree(src):删除文件夹,src表示源文件夹。区别这里和os模块中remove() 、rmdir()的用法、remove()方法只能删除某个文件,mdir()只能删除某个空文件夹。但是shutil模块中的rmtree()可以递归彻底删除非空文件夹;
3. glob库

glob库,提供了更加便捷的用来查找符合特定规则的目录和文件的方法,主要它支持*、**、? 、[ ]这四个通配符。

  • *:匹配0个或多个字符;
  • **:匹配所有文件、目录、子目录和子目录里的文件(3.5版本新增);
  • ?:匹配一个字符;
  • []:匹配指定范围内的字符,如[0-9]匹配数字,[a-z]匹配小写字母;
4. pathlib库

pathlib库中有一些功能超级棒,其中我最喜欢下面这个功能:

  • p.name:获取文件名;
  • p.suffix:获取文件后缀;

有了上述说明,下面详细为大家介绍4个库它们各自的用法。

三、os库

1. 模块的安装和导入
代码语言:javascript
复制
# 导入
import os
2. os.getcwd()
  • 作用:获取当前的工作路径;
代码语言:javascript
复制
os.getcwd()

结果如下:

3. os.listdir(path)
  • 作用:传入任意一个path路径,返回的是该路径下所有文件和目录组成的列表;
代码语言:javascript
复制
path = r"C:\Users\黄伟\Desktop\publish\os模块\test_os模块"
os.listdir(path)

结果如下:

4. os.walk(path)
  • 含义 :传入任意一个path路径,深层次遍历指定路径下的所有子文件夹,返回的是一个由路径、文件夹列表、文件列表组成的元组。我代码中写的方式属于元组拆包
  • 元组拆包:就是将一个元组中的每个值,赋值给不同的变量;
代码语言:javascript
复制
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")

结果如下:

5. os.path.exists(path)
  • 含义:传入一个path路径,判断指定路径下的目录是否存在。存在返回True,否则返回False;
代码语言:javascript
复制
path1 = 'C:\\Users\\黄伟\\Desktop\\publish\\os模块\\huang_wei'

if os.path.exists(path1):
    print("指定文件夹存在")
else:
    print("指定文件夹不存在")

结果如下:

6. os.mkdir(path)
  • 含义:传入一个path路径,创建单层(单个)文件夹;
  • 注意:如果文件夹已经存在,就会报错。因此创建文件夹之前,需要使用os.path.exists(path)函数判断文件夹是否存在;
代码语言:javascript
复制
os.getcwd()
path1 = os.getcwd()+"\\huang_wei"
os.mkdir(path1)

结果如下:

7. os.makedirs(path)
  • 含义:传入一个path路径,生成一个递归的文件夹;
  • 注意:如果文件夹存在,就会报错。因此创建文件夹之前,需要使用os.path.exists(path)函数判断文件夹是否存在;
代码语言:javascript
复制
os.getcwd()
path1 = os.getcwd()+"\\huang_wei"
os.mkdir(path1)

结果如下:

8. os.rmdir(path)
  • 含义:传入一个path路径,删除指定路径下的文件夹;
  • 注意:该方法只能删除空文件夹,删除非空文件夹会报错;
代码语言:javascript
复制
path1 = os.getcwd()+"\\huang_wei"
os.rmdir(path1)
----------------------------------
path2 = os.getcwd()+"\\a\\b\\c"
os.rmdir(path2) 

结果如下:

9. os.path.join(path1,path2)
  • 含义:传入两个path路径,将该路径拼接起来,形成一个新的完整路径;
代码语言:javascript
复制
path = os.getcwd()
lis = ["a.jpg","b.jpg","c.jpg"]
for i in lis:
    x = os.path.join(path,i)
    print(x)

结果如下:

10. os.path.split(path)
  • 含义:传入一个完整的path路径,将其拆分为绝对路径文件名2部分;
代码语言:javascript
复制
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.split(path1)

结果如下:

11. os.path.dirname(path)
  • 含义:传入一个完整的文件路径,只获取其绝对路径;
代码语言:javascript
复制
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.dirname(path1)

结果如下:

12. os.path.basename(path)
  • 含义:传入一个完整的文件路径,只获取其文件名;
代码语言:javascript
复制
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\a.jpg"
os.path.basename(path1)

结果如下:

13. os.path.isdir(path)
  • 含义:传入一个完整的文件路径,判断它是否是文件夹;
代码语言:javascript
复制
path = os.getcwd()
file_list = os.listdir()
for file in file_list:
    if os.path.isdir(file):
        print(file)

结果如下:

14. os.path.isfile(path)
  • 含义:传入一个完整的文件路径,判断它是否是文件;
代码语言:javascript
复制
path = os.getcwd()
file_list = os.listdir()
for file in file_list:
    if os.path.isfile(file):
        print(file)

结果如下:

15. os.path.sep
  • 含义:返回当前操作系统的路径分隔符;
代码语言:javascript
复制
os.path.sep

结果如下:

16. os.path.getsize(path)
  • 含义:传入一个完整的文件路径,返回该文件的大小;
代码语言:javascript
复制
os.path.getsize("我创建的压缩包.zip")

结果如下:

四、shutil库

本文所使用的素材,都是基于以下2个文件夹,其中一个文件夹为空。

1. 模块导入
代码语言:javascript
复制
import shutil
2. 复制文件
  • 函数:shutil.copy(src,dst)
  • 含义:复制文件;
  • 参数:src表示源文件,dst表示目标文件夹;
  • 注意:当移动到一个不存在的“目标文件夹”,系统会将这个不存在的“目标文件夹”识别为新的文件夹,而不会报错;
代码语言:javascript
复制
# 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”识别为文件名,而不是按照我们认为的,移动到一个新的不存在的文件夹。
"""

结果如下:

3. 复制文件夹
  • 函数:shutil.copytree(src,dst)
  • 含义:复制文件夹;
  • 参数:src表示源文件夹,dst表示目标文件夹;
  • 注意:这里只能是移动到一个空文件夹,而不能是包含其他文件的非空文件夹,否则会报错PermissionError;
① 如果目标文件夹中存在其他文件,会报错;
代码语言:javascript
复制
# 将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)

结果如下:

② 如果指定任意一个目标文件夹,则会自动创建;
代码语言:javascript
复制
# 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)

结果如下:

4. 移动文件或文件夹
  • 函数:shutil.move(src,dst)
  • 含义:移动文件/文件夹;-- 参数:src表示源文件/文件夹,dst表示目标文件夹;
  • 注意:文件/文件夹一旦被移动了,原来位置的文件/文件夹就没了。目标文件夹不存在时,会报错;
代码语言:javascript
复制
# 将当前工作目录下的“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)

结果如下:

注意:移动文件夹操作类似,我这里就不赘述了,自行下去学习。

5. 删除文件夹(慎用)
  • 函数:shutil.rmtree(src)
  • 含义:删除文件夹;
  • 参数:src表示源文件夹;
  • 注意:区别这里和os模块中remove()、rmdir()的用法,remove()方法只能删除某个文件,mdir()只能删除某个空文件夹。但是shutil模块中的rmtree()可以递归彻底删除非空文件夹;
代码语言:javascript
复制
# 将c文件夹彻底删除
src = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_c"
shutil.rmtree(src)

结果如下:

6. 创建和解压压缩包
  • zipobj.write():创建一个压缩包;
  • zipobj.namelist():读取压缩包中的文件信息;
  • zipobj.extract():将压缩包中的单个文件,解压出来;
  • zipobj.extractall():将压缩包中所有文件,解压出来;
  • shutil 模块对压缩包的处理是调用 ZipFile 和 TarFile这两个模块来进行的,因此需要导入这两个模块;
  • 注意:这里所说的压缩包,指的是“.zip”格式的压缩包;
① 创建一个压缩包
代码语言:javascript
复制
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)

结果如下:

② 读取压缩包中的文件信息
代码语言:javascript
复制
import zipfile

with zipfile.ZipFile("我创建的压缩包.zip", "r") as zipobj:
    print(zipobj.namelist())

结果如下:

③ 将压缩包中的单个文件,解压出来
  • 注意:目标文件夹不存在,会自动创建;
代码语言:javascript
复制
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)

结果如下:

④ 将压缩包中所有文件,解压出来;
  • 注意:目标文件夹不存在,会自动创建;
代码语言:javascript
复制
import zipfile
# 将压缩包中的所有文件,解压到d文件夹下
dst = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_d"
with zipfile.ZipFile("我创建的压缩包.zip", "r") as zipobj:
    zipobj.extractall(dst)

结果如下:

五、glob库

1. 支持4个常用的通配符

使用glob模块能够快速查找我们想要的目录和文件,就是由于它支持***?[ ]这三个通配符,那么它们到底是 什么意思呢?

  • *:匹配0个或多个字符;
  • **:匹配所有文件、目录、子目录和子目录里的文件(3.5版本新增);
  • ?:代匹配一个字符;
  • []:匹配指定范围内的字符,如[0-9]匹配数字,[a-z]匹配小写字母;
  • 注意:这3个通配符的用法,将在讲函数的时候,一起带大家操作一遍;
2. glob库中主要的3个函数

其实glob库很简单,只有3个主要函数供我们使用,它们分别是glob()iglob()escape()函数,因此学习起来特别容易。

  • glob.glob():返回符合匹配条件的所有文件的路径;
  • glob.iglob():返回一个迭代器对象,需要循环遍历获取每个元素,得到的也是符合匹配条件的所有文件的路径;
  • glob.escape():escape可以忽略所有的特殊字符,就是星号、问号、中括号,用处不大;
  • recursive=False:代表递归调用,与特殊通配符“**”一同使用,默认为False,False表示不递归调用,True表示递归调用;
① glob()函数
代码语言:javascript
复制
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)

结果如下:

② iglob()函数
代码语言:javascript
复制
path1 = r"C:\Users\黄伟\Desktop\publish\os模块\test_shutil_a\[0-9].png"
a = glob.iglob(path1)
for i in a:
    print(i)

结果如下:

③ escape()函数

通过下方两行代码的对比,可以看出escape()函数只是让*只表示它本来的意思,而不再具有通配符的作用。

代码语言:javascript
复制
glob.glob('t*')
glob.escape('t*')

结果如下:

通过上面的叙述可以知道,glob库其实并没有很多东西,就记住3个通配符3个函数即可。对于我们来说,glob库就是方便我们查找文件而诞生的,因此我们好好掌握glob()这一个函数,其实就够了,其它的知道、会用就行。

六、pathlib库

在使用之前,需要提前导入pathlib库。

代码语言:javascript
复制
from pathlib import Path
1. 最重要的Path对象

Path对象是这个库的核心,里面有着超级多好用的文件、文件夹处理方法,供我们调用。

① 当前路径下的Path对象
代码语言:javascript
复制
p = Path.cwd()
p

结果如下:

② 任意指定路径下的Path对象
代码语言:javascript
复制
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p

结果如下:

从上图可以看出,Path对象既可以是一个文件对象,也可以是一个文件夹对象。根据不同的对象,调用对应的方法,就可以很便捷的处理文件或文件夹。

2. 获取文件的具体信息

我们既然针对某个文件操作,所以首先应该获取到文件的Path对象。

代码语言:javascript
复制
p = Path("抽奖.txt")
p.stat()

结果如下:

3. 路径拼接

Path对象,进行路径拼接,直接使用一个/斜杠即可。

代码语言:javascript
复制
p = Path('C:/Users/Administrator/Desktop/python三剑客')
p1 = p/'pathlib库'
p1

结果如下:

4. 获取上级目录
代码语言:javascript
复制
p = Path.cwd()
p.parent
p.parent.parent

结果如下:

5. 获取文件的具体信息

我们既然针对某个文件操作,所以首先应该获取到文件的Path对象。

代码语言:javascript
复制
p = Path("抽奖.txt")
p.stat()

结果如下:

6. 获取指定路径下所有文件/文件夹的路径信息

以当前工作目录为例:在当前工作目录下,有下方这些文件。

如何获取每个文件对应的路径信息呢?

代码语言:javascript
复制
p = Path.cwd()
for i in p.iterdir():
    print(i)

结果如下:

「注意:」 iterdir()方法返回的是直接子文件或子文件夹【不考虑嵌套文件夹中的文件】。

7. 获取指定路径下"符合条件"文件的路径信息

仅想要获取直接子文件的路径信息,使用的是glob()方法。

代码语言:javascript
复制
p = Path.cwd()
file_list = p.glob('*.txt')
for file in file_list:
    print(file)

结果如下:

由于需求改变,我不仅想要获取直接子文件的信息,而且还要递归所有文件夹,找到所有符合条件的文件信息?这里有两种办法:

① 方法一
代码语言:javascript
复制
p = Path.cwd()
file_list = p.glob('**/*.txt')
for file in file_list:
    print(file)

结果如下:

② 方法二
代码语言:javascript
复制
p = Path.cwd()
file_list = p.rglob('*.txt')
for file in file_list:
    print(file)

结果如下:

综上所述:

  • Ⅰ 不考虑嵌套文件夹中的文件,使用glob()方法;
  • Ⅱ 考虑嵌套文件夹中的文件,使用rglob()方法;
8. 限制递归次数,访问嵌套文件夹

「一个粉丝留言问我:」 如果你有一个嵌套文件夹,嵌套次数很深。但是我们并不需要一直访问到最后一层,应该怎么办呢?

① 不限制递归次数
代码语言:javascript
复制
p = Path.cwd()
file_list = p.rglob('*.txt')

for file in file_list:
    print(file)

结果如下:

② 限制递归次数
代码语言:javascript
复制
p = Path.cwd()
file_list = p.rglob('*.txt')

for i,file in enumerate(file_list):
    if i <= 2:
        print(file)

结果如下:

9. 判断当前路径是否存在某个文件或者文件夹

这个需求很有用,比如我们做文件分类的时候,我们需要创建新的文件夹,用于文件分类。此时,我们需要判断,创建的文件夹是否是不存在的,只有不存在我们才去创建这个文件夹。

代码语言:javascript
复制
p = Path.cwd()

for i in p.iterdir():
    print(i)

结果如下:

如果有这么些文件,如何判断文件或文件夹,是否存在呢?

10. 创建文件夹

上面我们如果已经判断了不存在666.txt这个文件,而不存在'b'这个文件夹,现在我们就来创建它。

代码语言:javascript
复制
p = Path.cwd()
p1 = p/'b'

if not Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/b').exists():
    p1.mkdir()

结果如下:

上述我们已经为大家创建了单个文件夹,现在我们来创建一个递归文件夹,这里一定要使用parents=True参数。

代码语言:javascript
复制
p = Path.cwd()
p1 = p/'嵌套第一层'/'嵌套第二层'
p1.mkdir(parents=True)
11. 判断某个路径是文件,还是文件夹
代码语言:javascript
复制
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p.is_dir()
p.is_file()

结果如下:

12. 文件/文件夹重命名
代码语言:javascript
复制
p = Path('3.gif')
p.rename("重命名_3.gif")
13. 获取文件的文件名和后缀

这个功能真的很赞,超级好用。

代码语言:javascript
复制
p = Path('C:/Users/Administrator/Desktop/python三剑客/pathlib库/抽奖.txt')
p.name
p.suffix

结果如下:

我们要注意一点,os库shutil库glob库是互补的,我们要善于发挥各自的优势,充分利用它们的优势,帮助我们快速的操作文件和文件夹

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 快学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、开篇
  • 二、四大库各自好用的地方
    • 1. os库
      • 2. shutil库
        • 3. glob库
          • 4. pathlib库
          • 三、os库
            • 1. 模块的安装和导入
              • 2. os.getcwd()
                • 3. os.listdir(path)
                  • 4. os.walk(path)
                    • 5. os.path.exists(path)
                      • 6. os.mkdir(path)
                        • 7. os.makedirs(path)
                          • 8. os.rmdir(path)
                            • 9. os.path.join(path1,path2)
                              • 10. os.path.split(path)
                                • 11. os.path.dirname(path)
                                  • 12. os.path.basename(path)
                                    • 13. os.path.isdir(path)
                                      • 14. os.path.isfile(path)
                                        • 15. os.path.sep
                                          • 16. os.path.getsize(path)
                                          • 四、shutil库
                                            • 1. 模块导入
                                              • 2. 复制文件
                                                • 3. 复制文件夹
                                                  • 4. 移动文件或文件夹
                                                    • 5. 删除文件夹(慎用)
                                                      • 6. 创建和解压压缩包
                                                      • 五、glob库
                                                        • 1. 支持4个常用的通配符
                                                          • 2. glob库中主要的3个函数
                                                          • 六、pathlib库
                                                            • 1. 最重要的Path对象
                                                              • 2. 获取文件的具体信息
                                                                • 3. 路径拼接
                                                                  • 4. 获取上级目录
                                                                    • 5. 获取文件的具体信息
                                                                      • 6. 获取指定路径下所有文件/文件夹的路径信息
                                                                        • 7. 获取指定路径下"符合条件"文件的路径信息
                                                                          • 8. 限制递归次数,访问嵌套文件夹
                                                                            • 9. 判断当前路径是否存在某个文件或者文件夹
                                                                              • 10. 创建文件夹
                                                                                • 11. 判断某个路径是文件,还是文件夹
                                                                                  • 12. 文件/文件夹重命名
                                                                                    • 13. 获取文件的文件名和后缀
                                                                                    领券
                                                                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档