程序员文章、书籍推荐和程序员创业信息与资源分享平台

网站首页 > 技术文章 正文

Python内置模块:pathlib模块使用教程

hfteth 2025-08-03 04:56:13 技术文章 4 ℃

一、为什么选择pathlib?

传统的文件系统操作依赖osos.path模块,代码多为字符串拼接路径,可读性和面向对象特性较差。Python 3.4引入的pathlib模块提供了面向对象的路径操作方式,通过Path类封装了文件/目录的所有操作,代码更简洁、更易维护,是现代Python项目的推荐选择。


二、知识导图:pathlib核心体系


三、Path对象基础:核心类简介

3.1 Path类定义与构造

Path类是pathlib的核心,用于表示文件系统中的路径(文件或目录)。
原型

class pathlib.Path(*args, **kwargs)
  • 功能:封装路径字符串,提供面向对象的路径操作方法。
  • 参数:支持字符串、字节串、os.PathLike对象(如os.DirEntry)。
  • 注意:Python 3.6+支持pathlib.Path(字节串),但推荐使用字符串路径(跨平台兼容性更好)。

示例

from pathlib import Path

# 构造Path对象(自动识别操作系统路径分隔符)
path1 = Path("/home/user/doc.txt")  # Linux/macOS
path2 = Path("C:\\Program Files\\data.csv")  # Windows(反斜杠需转义或用原始字符串)
path3 = Path("data/logs")  # 相对路径(相对于当前工作目录)

3.2 路径属性(常用属性)

属性

说明

示例(假设path = Path("a/b/c.txt"))

name

路径的最后一部分(文件名或目录名)

'c.txt'

stem

文件名(不带后缀)

'c'

suffix

后缀(含点,如.txt)

'.txt'

suffixes

多后缀列表(如file.tar.gz的后缀是['.tar', '.gz'])

['.txt']

parent

父目录(Path对象)

Path('a/b')

parents

所有父目录的元组(最多6层)

(Path('a'), Path('/'))

parts

路径的各部分元组(按分隔符拆分)

('/', 'home', 'user', 'c.txt')

anchor

绝对路径的锚点(如C:\或/)

'/'(Linux)或'C:\\'(Windows)

示例代码

path = Path("data/reports/2025/sales.xlsx")
print(path.name)       # 输出:sales.xlsx
print(path.stem)       # 输出:sales
print(path.suffix)     # 输出:.xlsx
print(path.parent)     # 输出:data/reports/2025
print(path.parts)      # 输出:('data', 'reports', '2025', 'sales.xlsx')

四、路径操作:拼接、解析与规范化

4.1 路径拼接:joinpath()与/运算符

功能:将多个路径片段拼接成一个完整路径。
方法

  • Path.joinpath(*other):通过方法调用拼接。
  • 运算符/:更简洁的语法(推荐)。

示例

base = Path("/home/user")
full_path = base / "docs" / "notes.txt"  # 等价于 base.joinpath("docs", "notes.txt")
print(full_path)  # 输出:/home/user/docs/notes.txt

4.2 解析绝对路径:resolve()

功能:将相对路径转换为绝对路径,解析符号链接(可选)。
参数strict=False(若路径不存在,strict=True会抛出FileNotFoundError)。

示例

relative_path = Path("../data/file.txt")
abs_path = relative_path.resolve()  # 假设当前目录是/home/user/project
print(abs_path)  # 输出:/home/user/data/file.txt(假设../指向上级目录)

4.3 规范化路径:with_name()与with_suffix()

功能:修改路径的文件名或后缀。

  • with_name(name):替换文件名(保留父目录)。
  • with_suffix(suffix):替换后缀(自动处理重复点)。

示例

path = Path("old_name.txt")
new_name = path.with_name("new_name.md")  # 替换文件名和后缀
print(new_name)  # 输出:new_name.md

path = Path("image.tar.gz")
new_suffix = path.with_suffix(".zip")  # 替换最后一个后缀
print(new_suffix)  # 输出:image.tar.zip

五、文件操作:读写与管理

5.1 创建与删除文件:touch()与unlink()

方法

功能

参数

返回值

注意事项

Path.touch()

创建空文件(若存在则更新修改时间)

mode=0o666(权限)

None

若父目录不存在会抛出FileNotFoundError

Path.unlink()

删除文件(不存在时抛出FileNotFoundError)

None

不可用于删除目录(用rmdir())

示例

# 创建文件(自动创建父目录需配合mkdir)
log_path = Path("logs/app.log")
log_path.parent.mkdir(exist_ok=True)  # 若父目录不存在则创建(exist_ok=True避免报错)
log_path.touch()  # 创建空文件

# 写入内容(推荐用write_text)
log_path.write_text("[2025-07-15] 系统启动\n")  # 文本模式写入(自动编码为utf-8)

# 读取内容(推荐用read_text)
content = log_path.read_text()
print(content)  # 输出:[2025-07-15] 系统启动

# 删除文件
log_path.unlink()

5.2 读写文本/二进制文件:read_text()与write_text()

方法

功能

参数

返回值

Path.write_text(data, encoding='utf-8', errors=None)

写入文本到文件(覆盖原有内容)

data(字符串)

None

Path.read_text(encoding='utf-8', errors=None)

读取文本文件内容

字符串

技巧

  • 写入大文件时,建议用open()配合上下文管理器(with语句),但write_text已内部封装,更简洁。
  • 二进制文件操作用write_bytes()read_bytes()(参数为bytes类型)。

示例(二进制文件)

image_path = Path("photo.jpg")
with open(image_path, "rb") as f:
    image_data = f.read()
image_path.write_bytes(image_data)  # 写入二进制数据

六、目录操作:创建、遍历与删除

6.1 创建目录:mkdir()与mkdir(parents=True)

功能:创建目录(类似os.mkdir)。
参数

  • parents=False:若父目录不存在,True表示递归创建(类似os.makedirs)。
  • exist_ok=False:若目录已存在,True表示不报错(Python 3.5+)。

示例

data_dir = Path("data/2025/logs")
try:
    data_dir.mkdir(parents=True, exist_ok=True)  # 递归创建所有父目录(忽略已存在的)
except FileExistsError:
    print("目录已存在")

6.2 遍历目录:iterdir()与glob()

方法

功能

示例

Path.iterdir()

遍历目录下的所有条目(返回Path对象)

for entry in dir.iterdir():

Path.glob(pattern)

按通配符匹配路径(如*.txt)

for txt_file in dir.glob("*.txt"):

Path.rglob(pattern)

递归遍历所有子目录(如**/*.csv)

for csv_file in dir.rglob("*.csv"):

示例(批量处理日志文件)

log_dir = Path("logs")
# 遍历所有.txt文件
for log_file in log_dir.glob("*.txt"):
    print(f"处理文件:{log_file}")
    content = log_file.read_text()
    # 业务逻辑...

# 递归查找所有子目录中的.csv文件
for csv_file in log_dir.rglob("**/*.csv"):
    print(f"找到CSV文件:{csv_file}")

6.3 删除目录:rmdir()与unlink()(谨慎使用)

方法

功能

注意事项

Path.rmdir()

删除空目录(非空目录抛出OSError)

需确保目录为空,否则先用shutil.rmtree

Path.unlink()

删除文件(见5.1节)

不可用于删除目录

示例(安全删除空目录)

empty_dir = Path("temp/empty")
if empty_dir.exists() and empty_dir.is_dir() and not any(empty_dir.iterdir()):
    empty_dir.rmdir()
else:
    print("目录非空或不存在")

七、高级应用:元数据、符号链接与路径匹配

7.1 获取文件元数据:stat()

功能:获取文件的元数据(如大小、修改时间),返回os.stat_result对象(支持属性访问)。

常用属性

  • st_size:文件大小(字节)。
  • st_mtime:最后修改时间(时间戳,可用datetime.fromtimestamp()转换)。
  • st_ctime:创建时间(Windows)或最后元数据修改时间(Linux/macOS)。

示例

file_path = Path("data/report.pdf")
stat_info = file_path.stat()
print(f"文件大小:{stat_info.st_size} 字节")
print(f"最后修改时间:{datetime.fromtimestamp(stat_info.st_mtime).strftime('%Y-%m-%d %H:%M:%S')}")

7.2 符号链接:symlink_to()与resolve(strict=True)

方法

功能

参数

Path.symlink_to(target)

创建符号链接(指向target)

target(目标路径)

Path.resolve(strict=True)

解析符号链接(得到真实路径)

strict(是否严格检查)

示例

# 创建符号链接(Windows需管理员权限)
link_path = Path("link_to_doc")
doc_path = Path("/home/user/doc.txt")
link_path.symlink_to(doc_path)

# 解析符号链接(得到真实路径)
real_path = link_path.resolve(strict=True)
print(real_path)  # 输出:/home/user/doc.txt

7.3 路径匹配:match()

功能:检查路径是否匹配给定的glob模式(如*.txtdocs/**/*.md)。

示例

path = Path("docs/2025/notes.txt")
# 匹配子目录下的txt文件
print(path.match("docs/**/*.txt"))  # 输出:True
# 匹配以2025开头的目录
print(path.match("docs/2025/*"))    # 输出:True

八、对比os模块:pathlib的优势

操作场景

os模块(传统方式)

pathlib(现代方式)

优势

拼接路径

os.path.join("a", "b")

Path("a") / "b"

面向对象,链式调用更直观

创建文件

open("file.txt", "w").close()

Path("file.txt").touch()

自动处理父目录依赖(配合mkdir)

读取文件内容

open("file.txt").read()

Path("file.txt").read_text()

显式文本/二进制模式,编码自动处理

遍历目录

os.listdir() + os.path.isfile()

Path("dir").iterdir() + is_file()

直接返回Path对象,无需重复转换路径

获取文件大小

os.path.getsize("file.txt")

Path("file.txt").stat().st_size

元数据封装更完整,支持更多属性


九、应用示例:日志文件管理

9.1 需求描述

实现一个日志管理系统,功能包括:

  1. 自动创建日志目录(按日期划分,如logs/2025-07-15)。
  2. 写入实时日志(追加模式)。
  3. 定期清理7天前的日志文件。

9.2 代码实现(PEP8风格)

from pathlib import Path
from datetime import datetime, timedelta
import shutil

class LogManager:
    def __init__(self, log_root="logs"):
        self.log_root = Path(log_root)
        self.log_root.mkdir(exist_ok=True)  # 初始化根目录

    def _get_today_log_dir(self):
        """获取今日日志目录(格式:logs/YYYY-MM-DD)"""
        today = datetime.now().strftime("%Y-%m-%d")
        return self.log_root / today

    def write_log(self, message):
        """写入实时日志(追加模式)"""
        today_dir = self._get_today_log_dir()
        today_dir.mkdir(parents=True, exist_ok=True)  # 创建今日目录
        log_file = today_dir / "app.log"
        # 追加写入(自动换行)
        with log_file.open("a", encoding="utf-8") as f:
            f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {message}
")

    def clean_old_logs(self, days=7):
        """清理超过指定天数的日志目录"""
        cutoff_date = datetime.now() - timedelta(days=days)
        for date_dir in self.log_root.iterdir():
            if not date_dir.is_dir():
                continue
            try:
                dir_date = datetime.strptime(date_dir.name, "%Y-%m-%d")
            except ValueError:
                continue  # 跳过非日期格式的目录
            if dir_date < cutoff_date:
                shutil.rmtree(date_dir)  # 删除整个目录(pathlib不支持删非空目录)

# 使用示例
if __name__ == "__main__":
    log_manager = LogManager()
    log_manager.write_log("系统启动")
    log_manager.write_log("用户登录:admin")
    log_manager.clean_old_logs(days=30)  # 清理30天前的日志

十、学习路线

  1. 基础阶段:掌握Path类构造、路径属性(name, parent等)、路径拼接(/运算符)。
  2. 文件操作:熟练使用write_text()read_text()touch()unlink()
  3. 目录操作:学会mkdir()iterdir()glob()rmdir()
  4. 高级应用:元数据获取(stat())、符号链接(symlink_to())、路径匹配(match())。
  5. 实战项目:完成日志系统、配置文件管理、批量文件处理等项目。

十一、学习总结

  • 核心思想pathlib通过Path对象将路径抽象为文件系统实体,提供面向对象的API,代码更易读、易维护。
  • 实践建议: 优先使用Path对象替代字符串路径。 文件读写用read_text()/write_text()(文本)或read_bytes()/write_bytes()(二进制)。 目录操作前用exists()is_dir()检查存在性,避免异常。
  • 注意事项Path对象是不可变的(修改路径需重新赋值)。 跨平台时,Path自动处理分隔符(如/在Windows也有效)。 删除目录前确保为空(或用shutil.rmtree处理非空目录)。

通过本教程,我们可以掌握pathlib的核心用法,建议在实际项目中磨炼pathlib模块使用技能,提升代码质量!


持续更新Python编程学习日志与技巧,敬请关注!


#编程# #学习# #python# #在头条记录我的2025#


最近发表
标签列表