Python的路径操作(使用Pathlib、glob、shutil等库)

本文最后更新于:2022年7月21日 下午

Python的路径操作(使用pathlib、glob、shutil、os库)

在用Python处理数据时,经常需要进行读取遍历、复制移动、新建文件夹等操作,本文对比介绍Python中常用的各类路径操作,包括Pathlib、glob、shutil、os。

从下表可知,一般用来处理文件、路径的这四个库都是python内置的,很方便使用,其中pathlib和glob是文件路径的管理,而shutil是复制移动删除文件,os则是更广泛一些,不仅包含一些路径操作和文件操作,还有许多其他的功能。

Module 内容介绍 是否内置
pathlib 面向对象的文件管理库 内置
glob 使用Unix-style的文件名匹配扩展 内置
os 系统接口 内置
shutil 高级文件操作库 内置

路径管理的对比

在pathlib、glob、os中,pathlib是最简易使用的,符合面向对象的思路,同时也兼顾了性能和实用性。在我的另外一篇博客中有介绍:Python-Pathlib库基础使用教程 - Kamino’s Blog

这里对比一下三个库中类似的一些函数:

  1. pathlib.Path.glob(pattern)pathlib.Path.rglob(pattern)

    对一个Path对象下的,符合pattern的路径进行遍历。rglob不仅会匹配当前文件夹,还会递归的遍历子文件夹。pattern不是正则,只支持*匹配多个字符,?匹配单个字符,[]匹配括号中包含的字符。假如使用**匹配一个目录,则表示当前所有子目录以及递归下去的所有子目录。

    注意返回的顺序是arbitrary的(我试验是根据字母顺序排的,但是一般不利用这一点)

    注意返回的是iterator而不是list,这有利于处理许多文件。

    注意返回的iterator的元素也是Pathlike的对象

  2. glob.glob(pathname)glob.iglob(pathname)

    glob没有引入path对象,所以参数是一个完整的路径,匹配的规则也和pathlib的glob一样,递归可以用**表示。

    不同的是,glob通过传入recursive=True而不是用另一个函数来递归匹配。

    注意glob和iglob的区别是,glob返回列表,iglob返回iterator。

  3. os.listdir(path)os.walk()os.scandir()

    os.listdir(path)返回文件名而不是路径组成的列表。需要对每一个元素判断是目录还是文件。

    os.walk()遍历目录树,返回iterator,针对每个节点(目录)都生成一个三元组: (dirpath, dirnames, filenames),dirpath是当前节点的路径,而dirnames是当前节点下的目录的名字,filenames是当前节点下的文件的名字。

    os.scandir()返回目录下的文件的DirEntry对象组成的iterator。需要对每一个对象判断是目录还是文件。

⚠️ 注意pathlib.Path('.').glob('*')os的操作都返回当前目录下包括以.开头的文件和目录,而glob.glob('*')不会包括以.开头的。

在使用type-hint的时候,假如要提示传入一个路径,可以用os.PathLike

文件操作的对比

创建文件夹

创建文件夹用os、pathlib都可以,os中使用os.mkdir()来创建一个目录,但是要求父目录存在并且要创建的目录不存在。假如父目录不一定存在则可以使用os.makedirs(),同时这个函数也可以指定要创建的目录已经存在的情况。

pathlib.Path.mkdir()则合并了上面两个函数,用参数确定需不需要父目录存在和目录已存在的处理方式。

两者都可以指定创建文件夹的权限。

复制、删除、移动文件

这些操作乖乖用shutil最方便

shutil.copyfile(src,dst)是最快的复制文件内容(无元数据)从src到dst的方法,dst必须要是完整的文件的名字

shutil.copy(src,dst)是复制文件到目录或者另一个文件的方法,这里dst可以是一个目录,表示复制到该目录下。

shutil.copy2(src,dst)同上,但是copy2还会保留元信息。

shutil.copytree(src,dst)是复制文件夹,会保留元信息。

shutil.rmtree(path)是递归删除一个文件夹。

shutil.move(src,dst)是移动一个文件或者文件夹,可以通过参数来指定移动时使用copy还是copy2的方法。