告别os.path,拥抱pathlib

pathlib 模块是在Python3.4版本中首次被引入到标准库中的,作为一个可选模块。

Python3.6开始,内置的 open 函数以及 osshutilos.path 模块中的各种函数都可以正确地使用 pathlib.Path 对象了。

最初,pathlib给人的感觉只是os.path的一个不必要的面向对象版本,

不过,当你实际去了解pathlib之后,会发现pathlib实际上绝不是一个简单的面向对象版本,

而是实实在在的解决了os.path存在的一些问题。

1. os.path VS pathlib

1.1. 路径规范化

对于os.path来说,路径的分隔用正斜杆\)还是反斜杠/)需要自己根据操作系统来确定。

或者,每一个路径拼接的地方,都用os.path.join来连接。

而使用pathlib的话,直接用反斜杠/)即可,不用担心操作系统的不同。

比如:

python 复制代码
import os

# windows系统中测试

os.path.join("a/b", "c.txt")
# 运行结果 错误
# 'a/b\\c.txt'

os.path.join("a", "b", "c.txt")
# 运行结果 正确
# 'a\\b\\c.txt'

从代码可以看出,每一层文件夹都必须用join连接才能正确适应不同系统。

而在pathlib中,则不需要考虑这么多。

python 复制代码
from pathlib import Path

Path("a/b").joinpath("c.txt")
# WindowsPath('a/b/c.txt')

Path("a").joinpath("b").joinpath("c.txt")
# WindowsPath('a/b/c.txt')

使用pathlib,在windows或者linux中,统一使用反斜杠/)来分隔文件夹。

路径规范化之后的好处就是代码更加简洁。

比如:下面这个重命名文件的例子(a/b/c/d.csv => a/b/c.csv

python 复制代码
# os.path 方式
os.rename(os.path.join("a", "b", "c", "d.csv"), os.path.join("a", "b", "c.csv"))

# pathlib 方式
Path("a/b/c/d.csv").reanme("a/b/c.csv")

哪种方式更清晰简洁不言而喻。

1.2. 字符串和对象

为什么要用对象来表示路径?

先看下面3个字符串变量:

python 复制代码
student = '{"name": "databook", "score": "90"}'
graduate_date = "2023-07-01"
home_directory = '/home/databook'

这3个字符串其实代表不同的事物:一种是 JSON blob,一种是日期,一种是文件路径。

再看下面3个用对象表示的变量:

python 复制代码
from datetime import date
from pathlib import Path

student = {"name": "databook", "score": "90"}
graduate_date = date(2023, 7, 1)
home_directory = Path('/home/databook')

用字符串来表示变量确实简洁,但也导致每个变量失去了其本身的意义,

程序无法区分这个变量代表的是JSON,还是日期,还是一个路径,从而增加了程序的不确定性。

程序规模大了,或者复杂性提高了之后,存在很大的隐患。

os.pathpathlib就是这样的关系,os.path使用字符串表示路径,pathlib使用Path对象表示路径。

1.3. 读写文件

pathlib的路径对象(Path)可以直接读写文件,因此也能大大简化读写文件的代码。

不用pathlib的读写文件方式:

python 复制代码
import os

# 读取文件
fp = os.path.join("a", "b.txt")
with open(fp, "r") as f:
    f.read()

# 写入文件
with open(fp, "w") as f:
    f.write("hello")

使用pathlib的话:

python 复制代码
from pathlib import Path

# 读取文件
Path("a/b.txt").read_text()

# 写入文件
Path("a/b.txt").write_text("hello)

2. pathlib的性能

pathlib用面向对象的方式处理路径,难免让人觉得会比传统的方式慢很多,也就是存在性能问题。

那么,pathlib到底会比传统方式慢多少?通过下面的简单示例来看看。

传统方式:

python 复制代码
def a(d="D:/miniconda3/Lib/site-packages"):
    from os import getcwd, walk

    extension = ".py"
    count = 0
    for root, directories, filenames in walk(d):
        for filename in filenames:
            if filename.endswith(extension):
                count += 1
                
    print(f"{count} Python files found")

if __name__ == "__main__":
    import time

    t0 = time.time()
    a()
    t1 = time.time()
    print(t1 - t0)

# 运行结果:
7875 Python files found
0.31201744079589844

pathlib方式:

python 复制代码
def b(d="D:/miniconda3/Lib/site-packages"):
    from pathlib import Path

    extension = ".py"
    count = 0
    for filename in Path(d).rglob(f"*{extension}"):
        count += 1

    print(f"{count} Python files found")

if __name__ == "__main__":
    import time

    t0 = time.time()
    b()
    t1 = time.time()
    print(t1 - t0)

# 运行结果:
7875 Python files found
0.44898128509521484

读取的标准库中的文件,总共将近8000个文件,运行多次后,时间大概相差0.1秒 左右。
pathlib的性能确实略逊于传统方式,但是将近8000个文件,也只慢了0.1秒

如果不是大规模处理文件的话,还是用pathlib更好。

3. 总结

总的来说,与传统的 os.path 模块相比,pathlib 提供了一种更现代和面向对象的方式来处理文件路径。

它支持跨平台的文件路径操作,使得开发者可以更容易地编写可移植的代码。

此外,pathlib 还提供了链式调用的能力,使得代码更加简洁和易读。

因此,为了代码更加简洁、易读和可维护,推荐使用 pathlib 来替代传统的 os.path

相关推荐
海天一色y21 分钟前
Pycharm(十六)面向对象进阶
ide·python·pycharm
??? Meggie22 分钟前
【Python】保持Selenium稳定爬取的方法(防检测策略)
开发语言·python·selenium
XIE3921 小时前
Browser-use使用教程
python
酷爱码2 小时前
如何通过python连接hive,并对里面的表进行增删改查操作
开发语言·hive·python
蹦蹦跳跳真可爱5892 小时前
Python----深度学习(基于深度学习Pytroch簇分类,圆环分类,月牙分类)
人工智能·pytorch·python·深度学习·分类
MinggeQingchun5 小时前
Python - 爬虫-网页解析数据-库lxml(支持XPath)
爬虫·python·xpath·lxml
Python自动化办公社区6 小时前
Python 3.14:探索新版本的魅力与革新
开发语言·python
weixin_贾7 小时前
最新AI-Python机器学习与深度学习技术在植被参数反演中的核心技术应用
python·机器学习·植被参数·遥感反演
张槊哲8 小时前
函数的定义与使用(python)
开发语言·python
船长@Quant8 小时前
文档构建:Sphinx全面使用指南 — 实战篇
python·markdown·sphinx·文档构建