pathlib — 面向对象的文件系统路径

1. pathlib 取代os.path模块

从python3.4开始,pathlib正式成为标准库,旨在取代老旧的os.path模块和一些os模块中对系统路径的操作。pathlib提供了表示文件系统路径的类,而os.path提供的是各种操作路径的函数,如果你已经熟练的掌握了os.path,那么学习pathlib将非常容易。

从使用情况来看,pathlib的功能对编程人员更加友好,对系统路径的操作更便捷。

2. 纯路径与具体路径

下图是pathlib所提供的类的继承关系

纯路径与具体路径的区别在于,具体路径类可以对系统路径进行I/O操作,而纯路径则不可以,那么纯路径类能做什么呢?纯路径类可以对路径进行计算,这种计算不涉及I/O操作,比如获得文件的后缀

from pathlib import PurePath

path = PurePath('/home/root/1.txt')
suffix = path.suffix
print(suffix)       # .txt

获得文件路径的后缀,纯粹是一个字符串计算的操作,不涉及到I/O操作,如果你对路径的操作都属于这种类型的,那么用纯路径类就可以。那么,具体路径的所谓I/O操作是什么呢,举一个简单的例子,判断路径是否存在。想要判断一个路径是否存在,就一定需要访问操作系统,只有操作系统才知道一个路径是否存在。在上面的代码里,你不能用path对象去调用exists方法,因为PurePath类根本没有这个方法,你需要使用Path类才可以

from pathlib import Path

path = Path('/home/root/1.txt')
suffix = path.suffix
print(suffix)       # .txt
print(path.exists())    # False

PurePath 是Path的父类,因此如果你分不清该用纯路径类还是具体路径类,那么使用Path类就好了。至于PosixPath 和 WindowsPath,如果你也分不清应当依据什么进行选择,那就不要选了,一劳永逸的选择Path就好了,python会根据你的系统自动为你选择。上面的代码,如果在windows平台上执行,path.__class__ 的值是pathlib.WindowsPath, 如果是在linux系统上执行,path.__class__ 的值是pathlib.PosixPath。

3. pathlib方法与os.path函数对照关系

如果你对os.path比较熟悉,那么在学习pathlib时,可以参考下表中方法与函数的对照关系

os 和 os.path

pathlib

os.path.abspath()

Path.resolve()

os.chmod()

Path.chmod()

os.mkdir()

Path.mkdir()

os.rename()

Path.rename()

os.replace()

Path.replace()

os.rmdir()

Path.rmdir()

os.remove(), os.unlink()

Path.unlink()

os.getcwd()

Path.cwd()

os.path.exists()

Path.exists()

os.path.expanduser()

Path.expanduser()Path.home()

os.path.isdir()

Path.is_dir()

os.path.isfile()

Path.is_file()

os.path.islink()

Path.is_symlink()

os.stat()

Path.stat(), Path.owner(), Path.group()

os.path.isabs()

PurePath.is_absolute()

os.path.join()

PurePath.joinpath()

os.path.basename()

PurePath.name

os.path.dirname()

PurePath.parent

os.path.samefile()

Path.samefile()

os.path.splitext()

PurePath.suffix

4. 用的比较爽的方法

4.1 获得上层文件夹

在工程上,你可能需要通过当前的一个已知路径,向上回去几层,去定位一个文件夹或者文件,比如给定一个路径 /home/root/python/1.txt,向上回溯两层,得到的路径是/home/root,使用os.path模块,你可以这样编写代码

path = os.path.dirname('/home/root/python/1.txt')
path = os.path.dirname(path)
print(path)

向上回溯N层,需要调用N次dirname函数,着实麻烦,如果用pathlib,简直不要太简单

from pathlib import Path

path = Path('/home/root/python/1.txt')
print(path.parents[1])      # /home/root

回溯3层,取path.parents[2]即可,怎么样,是不是方便了许多。

4.2 遍历文件夹及其子文件夹

使用os.walk函数,可以实现对文件夹的深层遍历

for dir_path,subpaths,files in os.walk('./',False):
    for file in files:
        file_path = os.path.join(dir_path,file)
        if file_path.endswith(".py"):
            print(file_path)

上面的代码,可以输出当前目录下所有的文件夹和文件,如果只想要某种后缀的文件,那么需要你对file_path的后缀进行判断,而使用Path的glob方法,将更加容易。

py_files = path.glob("**/*.py")
for filename in py_files:
    print(filename)

"**" 是递归通配符,意味着对当前目录和子目录进行递归遍历,*.py 会匹配所有以.py结尾的文件路径。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案