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
这里对比一下三个库中类似的一些函数:
-
pathlib.Path.glob(pattern)
和pathlib.Path.rglob(pattern)
对一个Path对象下的,符合pattern的路径进行遍历。rglob不仅会匹配当前文件夹,还会递归的遍历子文件夹。pattern不是正则,只支持
*匹配多个字符,?匹配单个字符,[]匹配括号中包含的字符
。假如使用**匹配一个目录,则表示当前所有子目录以及递归下去的所有子目录。注意返回的顺序是arbitrary的(我试验是根据字母顺序排的,但是一般不利用这一点)。
注意返回的是iterator而不是list,这有利于处理许多文件。
注意返回的iterator的元素也是Pathlike的对象
-
glob.glob(pathname)
和glob.iglob(pathname)
glob没有引入path对象,所以参数是一个完整的路径,匹配的规则也和pathlib的glob一样,递归可以用
**
表示。不同的是,glob通过传入
recursive=True
而不是用另一个函数来递归匹配。注意glob和iglob的区别是,glob返回列表,iglob返回iterator。
-
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的方法。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!