当前位置: 首页 > news >正文

【Python基础】Python路径操作全解析:os.path、glob与pathlib从入门到精通

目录

  • Python路径操作全解析:os.path、glob与pathlib从入门到精通
    • 一、路径操作的必要性与背景
    • 二、os.path 模块:传统路径处理
      • 1. 设计哲学
      • 2. 核心函数详解
        • (1) 路径拼接
        • (2) 路径信息获取
        • (3) 路径类型判断
        • (4) 路径解析
      • 3. os.path 的局限性
    • 三、glob 模块:路径模式匹配
      • 1. 基本用法
      • 2. glob 的高级模式匹配
      • 3. glob 的参数
      • 4. glob 的应用场景
    • 四、pathlib 模块:现代路径处理
      • 1. 设计哲学
      • 2. 基本用法
        • (1) 创建Path对象
        • (2) 路径操作
        • (3) 遍历目录
        • (4) 文件操作
        • (5) 路径解析与规范化
        • (6) 文件权限操作
        • (7) 递归遍历与文件操作
        • (8) 路径安全处理
      • 3. pathlib 与 os.path 对比
    • 五、补充其他路径相关模块
      • 1. shutil 模块:高级文件操作
        • 设计哲学
        • 常用函数详解
        • 实战案例:备份目录
      • 2. tempfile 模块:安全临时文件操作
        • 设计哲学
        • 常用函数详解
      • 3. fnmatch 模块:文件名模式匹配
        • 设计哲学
        • 常用函数详解
        • 实战案例:过滤文件列表
    • 六、各个方法之间的对比
      • 1. 路径操作的演进
      • 2. 模块对比表
      • 3. 选择建议
      • 4. 代码风格对比
      • 5. EAFP vs LBYL 风格
    • 七、高级技巧与实战案例
      • 1. 批量修改文件扩展名
      • 2. 构建目录树统计器
      • 3. 路径安全处理
      • 4. 跨平台路径处理
      • 5. 文件处理工作流
      • 6. 安全路径操作函数
    • 八、常见问题与解决
      • 1. 为什么在Windows上使用pathlib时路径显示为反斜杠?
      • 2. 如何处理路径中的空格和特殊字符?
      • 3. 如何在不同系统间共享路径?
    • 九、总结与建议

Python路径操作全解析:os.path、glob与pathlib从入门到精通

一、路径操作的必要性与背景

在文件系统操作中,路径处理是基础且关键的环节。不同操作系统使用不同的路径分隔符(Windows用\,Unix-like系统用/),手动处理路径容易导致代码不可移植。Python提供了多个模块来解决这个问题,其中最常用的是os.pathglobpathlib

二、os.path 模块:传统路径处理

1. 设计哲学

  • 过程式路径处理:基于字符串的函数集合
  • 典型特征:需要组合多个函数完成复杂操作,路径作为普通字符串处理

2. 核心函数详解

(1) 路径拼接
import os
# 传统方式
path = os.path.join("/home/user", "documents", "file.txt")
# 结果:/home/user/documents/file.txt
(2) 路径信息获取
# 获取最后修改时间
mtime = os.path.getmtime("file.txt")  # 返回纪元秒数# 获取文件大小
size = os.path.getsize("file.txt")  # 返回字节数# 获取路径的ctime
ctime = os.path.getctime("file.txt")  # Unix上是元数据最后修改时间,Windows上是创建时间
(3) 路径类型判断
# 判断是否是绝对路径
is_abs = os.path.isabs("/home/user")  # True# 判断是否是文件
is_file = os.path.isfile("/home/user/file.txt")  # True/False# 判断是否是目录
is_dir = os.path.isdir("/home/user")  # True/False# 判断是否是符号链接
is_link = os.path.islink("/home/user/link")  # True/False# 判断是否是挂载点
is_mount = os.path.ismount("/home")  # True/False
(4) 路径解析
# 分离路径的目录和文件名
directory, filename = os.path.split("/home/user/file.txt")
# directory: /home/user, filename: file.txt# 获取文件名
filename = os.path.basename("/home/user/file.txt")  # file.txt# 获取目录名
dirname = os.path.dirname("/home/user/file.txt")  # /home/user# 分离文件名和扩展名
name, ext = os.path.splitext("report.txt")
# name: report, ext: .txt

3. os.path 的局限性

  • 函数式风格:需要频繁调用多个函数,代码零散
  • 字符串处理:路径作为字符串处理,容易出错
  • 平台差异:需要手动处理路径分隔符差异
  • 状态无感知:无状态操作,不跟踪当前工作目录

三、glob 模块:路径模式匹配

1. 基本用法

import glob# 查找所有txt文件
txt_files = glob.glob("*.txt")
# 结果:['file1.txt', 'file2.txt', ...]# 查找所有子目录下的txt文件
all_txt_files = glob.glob("**/*.txt", recursive=True)

2. glob 的高级模式匹配

import glob# 匹配以数字开头的文件
num_files = glob.glob("[0-9]*.txt")# 匹配特定扩展名
pdf_files = glob.glob("*.pdf")# 匹配多个模式
files = glob.glob("*.txt|*.csv", recursive=True)  # 仅在Python 3.10+支持

3. glob 的参数

# GLOB_MARK: 在每个返回的项目中加一个斜线
files = glob.glob("*.txt", flags=glob.GLOB_MARK)# GLOB_NOSORT: 按照文件在目录中出现的原始顺序返回
files = glob.glob("*.txt", flags=glob.GLOB_NOSORT)# GLOB_NOCHECK: 如果没有文件匹配则返回用于搜索的模式
files = glob.glob("*.nonexistent", flags=glob.GLOB_NOCHECK)# GLOB_ONLYDIR: 仅返回与模式匹配的目录项
dirs = glob.glob("*.dir", flags=glob.GLOB_ONLYDIR)

4. glob 的应用场景

  • 遍历目录中的特定类型文件
  • 检索符合特定命名模式的文件
  • 与os.path结合进行高级路径处理

四、pathlib 模块:现代路径处理

1. 设计哲学

  • 面向对象路径操作:路径即对象(Path实例)
  • 核心优势
    • 支持链式方法调用
    • 自动处理平台差异
    • 集成文件系统操作

2. 基本用法

(1) 创建Path对象
from pathlib import Path# 从字符串创建
file_path = Path("data/report.txt")# 从其他Path对象创建
base_path = Path("/home/user")
data_path = base_path / "data"  # /home/user/data# 从当前工作目录创建
cwd = Path.cwd()  # 当前工作目录# 从主目录创建
home = Path.home()  # 主目录
(2) 路径操作
# 路径拼接(使用/运算符)
path = Path("/home") / "user" / "data" / "file.txt"# 获取文件名
filename = path.name  # file.txt# 获取扩展名
ext = path.suffix  # .txt# 获取父目录
parent = path.parent  # /home/user/data# 获取文件大小
size = path.stat().st_size# 获取最后修改时间
mtime = path.stat().st_mtime# 判断文件是否存在
exists = path.exists()# 判断是否是文件
is_file = path.is_file()# 判断是否是目录
is_dir = path.is_dir()
(3) 遍历目录
# 查找当前目录下所有txt文件
txt_files = list(Path.cwd().glob("*.txt"))# 查找所有子目录下的txt文件
all_txt_files = list(Path.cwd().rglob("*.txt"))
(4) 文件操作
# 读取文件内容
content = Path("file.txt").read_text(encoding="utf-8")# 写入文件
Path("new_file.txt").write_text("Hello, World!", encoding="utf-8")# 创建目录
Path("new_dir").mkdir(exist_ok=True)# 重命名文件
Path("old.txt").rename("new.txt")# 删除文件
Path("file.txt").unlink()
(5) 路径解析与规范化
from pathlib import Path# 获取绝对路径
absolute_path = Path("relative/path").resolve()# 处理符号链接
resolved_path = Path("symlink").resolve()# 获取相对于某个路径的相对路径
relative_path = Path("current_dir/file.txt").relative_to(Path("current_dir"))
(6) 文件权限操作
from pathlib import Pathp = Path("file.txt")# 获取文件权限
permissions = p.stat().st_mode# 更改文件权限
p.chmod(0o644)  # 读写权限给用户,读权限给组和其他用户# 获取文件所有者
owner = p.owner()
group = p.group()
(7) 递归遍历与文件操作
from pathlib import Path# 递归遍历所有文件
for file in Path.cwd().rglob("*"):if file.is_file():print(f"文件: {file}")else:print(f"目录: {file}")# 读取所有文本文件
text_files = [f for f in Path.cwd().rglob("*.txt") if f.is_file()]
for file in text_files:print(file.read_text(encoding="utf-8"))
(8) 路径安全处理
from pathlib import Pathdef safe_path(path: str) -> Path:"""确保路径是安全的,不包含恶意路径"""p = Path(path).resolve()# 确保路径在安全目录内if not p.is_relative_to(Path.cwd()):raise ValueError("路径超出安全范围")return p# 示例
try:safe_file = safe_path("../malicious/file.txt")
except ValueError as e:print(f"安全错误: {e}")

3. pathlib 与 os.path 对比

功能描述os.path 方法pathlib 方法
路径拼接os.path.join()/ 运算符或 .joinpath()
获取文件名os.path.basename().name 属性
获取父目录os.path.dirname().parent 属性
获取扩展名os.path.splitext()[1].suffix 属性
判断文件存在os.path.exists().exists() 方法
判断是否为文件os.path.isfile().is_file() 方法
判断是否为目录os.path.isdir().is_dir() 方法
获取绝对路径os.path.abspath().resolve() 方法
路径规范化os.path.normpath().resolve(strict=False)
相对路径转换os.path.relpath().relative_to() 方法
获取文件大小os.path.getsize().stat().st_size
获取最后修改时间os.path.getmtime().stat().st_mtime
创建目录os.mkdir().mkdir(parents=True)
删除文件os.remove().unlink()
删除空目录os.rmdir().rmdir()

五、补充其他路径相关模块

1. shutil 模块:高级文件操作

设计哲学
  • 高阶文件操作:提供比os更高层次的文件操作函数
  • 核心优势:简化文件复制、移动、归档等复杂操作
常用函数详解
import shutil
from pathlib import Path# 复制文件(保留元数据)
shutil.copy("source.txt", "destination.txt")# 复制文件(保留所有元数据,包括时间戳)
shutil.copy2("source.txt", "destination2.txt")# 递归复制目录
shutil.copytree("source_dir", "destination_dir")# 移动/重命名文件或目录
shutil.move("old_name.txt", "new_name.txt")# 递归删除目录(包括其内容)
shutil.rmtree("directory_to_delete")# 创建归档文件(如zip、tar等)
shutil.make_archive("archive", "zip", "directory_to_compress")# 解压归档文件
shutil.unpack_archive("archive.zip", "extract_dir")
实战案例:备份目录
def backup_directory(src_dir, backup_dir):"""创建目录的备份"""backup_path = Path(backup_dir) / Path(src_dir).nameif backup_path.exists():shutil.rmtree(backup_path)shutil.copytree(src_dir, backup_path)print(f"已备份到: {backup_path}")

2. tempfile 模块:安全临时文件操作

设计哲学
  • 安全创建临时文件:避免与其他进程的临时文件冲突
  • 自动清理:默认在文件对象关闭后自动删除
常用函数详解
import tempfile
import os# 创建临时文件(不自动删除)
with tempfile.NamedTemporaryFile(delete=False) as tmp:tmp.write(b"Temporary content")temp_path = tmp.name# 读取临时文件
with open(temp_path, 'r') as f:print(f.read())# 删除临时文件
os.unlink(temp_path)# 创建临时目录
temp_dir = tempfile.mkdtemp()
print(f"临时目录: {temp_dir}")
# 使用后删除
shutil.rmtree(temp_dir)# 临时文件对象(自动删除)
with tempfile.NamedTemporaryFile() as tmp:tmp.write(b"Auto-deleted content")print("临时文件已创建,将在退出时自动删除")

3. fnmatch 模块:文件名模式匹配

设计哲学
  • 轻量级文件名匹配:专注于单个文件名的匹配,比glob更轻量
  • 与glob相似但更简单:适合不需要递归匹配的场景
常用函数详解
import fnmatch# 检查文件名是否匹配模式(不区分大小写)
print(fnmatch.fnmatch("report.pdf", "*.pdf"))  # True
print(fnmatch.fnmatch("Report.PDF", "*.pdf"))  # True (默认不区分大小写)# 区分大小写匹配
print(fnmatch.fnmatchcase("Report.PDF", "*.pdf"))  # False# 遍历目录匹配文件
for file in os.listdir("."):if fnmatch.fnmatch(file, "*.txt"):print(f"匹配的文本文件: {file}")
实战案例:过滤文件列表
def filter_files(file_list, pattern):"""过滤文件列表,返回匹配模式的文件"""return [f for f in file_list if fnmatch.fnmatch(f, pattern)]

六、各个方法之间的对比

1. 路径操作的演进

  • 传统方式:字符串拼接(不推荐)
  • 过渡方式:os.path(字符串处理,功能有限)
  • 现代方式:pathlib(面向对象,代码简洁,跨平台)
  • 高级操作:shutil(高级文件操作)
  • 模式匹配:glob(高效文件匹配)
  • 安全操作:tempfile(安全临时文件)

2. 模块对比表

模块/库适用场景优点缺点推荐度
os基础系统交互通用,广泛使用代码不直观★★★☆
os.path路径字符串处理与os配合仍然基于字符串★★☆
pathlib现代路径操作面向对象,代码简洁,跨平台需要Python 3.4+★★★★
glob模式匹配文件简单高效的文件匹配仅用于匹配★★★★
shutil高级文件操作简化复制、移动、归档仅用于操作★★★★
tempfile临时文件安全创建临时文件仅用于临时文件★★★☆
fnmatch文件名匹配轻量级匹配仅用于单个文件名★★★

3. 选择建议

场景推荐工具说明
基础路径处理pathlib代码简洁,跨平台
文件复制/移动shutil简化高级文件操作
文件模式匹配glob高效查找匹配文件
临时文件tempfile安全创建临时文件
文件名匹配fnmatch轻量级匹配,适合单个文件
旧代码维护os.path保持与现有代码一致

4. 代码风格对比

os.path 风格 (传统)

import osfile_path = os.path.join(os.path.dirname(__file__), "data", "report.txt")
if os.path.exists(file_path) and os.path.isfile(file_path):with open(file_path, 'r') as f:content = f.read()

pathlib 风格 (现代)

from pathlib import Pathfile_path = Path(__file__).parent / "data" / "report.txt"
if file_path.exists() and file_path.is_file():content = file_path.read_text(encoding="utf-8")

5. EAFP vs LBYL 风格

EAFP (Easier to Ask for Forgiveness than Permission)

from pathlib import Pathtry:content = Path("file.txt").read_text()print("文件存在且可读取")
except FileNotFoundError:print("文件不存在")
except PermissionError:print("没有读取权限")

LBYL (Look Before You Leap)

from pathlib import Pathpath = Path("file.txt")
if path.exists() and path.is_file() and path.is_readable():content = path.read_text()
else:print("文件不存在或不可读")

七、高级技巧与实战案例

1. 批量修改文件扩展名

# 使用pathlib
from pathlib import Pathfor p in Path("reports").glob("*.txt"):p.rename(p.with_suffix(".md"))# 使用os.path
import os
for root, _, files in os.walk("reports"):for f in files:if f.endswith(".txt"):old_path = os.path.join(root, f)new_path = os.path.splitext(old_path)[0] + ".md"os.rename(old_path, new_path)

2. 构建目录树统计器

from pathlib import Pathdef analyze_dir(path: Path):return {"dir_count": sum(1 for _ in path.rglob("*/")),"file_count": sum(1 for _ in path.rglob("*") if _.is_file())}result = analyze_dir(Path.cwd())
print(f"目录数: {result['dir_count']}, 文件数: {result['file_count']}")

3. 路径安全处理

from pathlib import Pathdef safe_path(path: str) -> Path:"""确保路径是安全的,不包含恶意路径"""p = Path(path).resolve()if not p.is_absolute():p = p.resolve()return p# 示例
safe_file = safe_path("../malicious/file.txt")
print(safe_file)  # 将转换为绝对路径,避免目录遍历攻击

4. 跨平台路径处理

from pathlib import Path# 跨平台路径拼接
path = Path("data") / "images" / "photo.jpg"# 获取平台特定的分隔符
separator = Path.sep  # '/' on Unix, '\' on Windows# 转换为字符串(自动处理平台差异)
str_path = str(path)  # 在Windows上会是"data\images\photo.jpg"

5. 文件处理工作流

from pathlib import Path
import shutil
import globdef process_files(source_dir, destination_dir, pattern="*.txt"):"""处理匹配模式的文件,复制到目标目录"""source = Path(source_dir)dest = Path(destination_dir)# 创建目标目录dest.mkdir(parents=True, exist_ok=True)# 处理所有匹配的文件for file in source.glob(pattern):if file.is_file():# 创建安全的文件名safe_name = file.name.replace(" ", "_")dest_file = dest / safe_name# 复制文件(保留元数据)shutil.copy2(file, dest_file)# 添加处理日志print(f"已处理: {file} -> {dest_file}")print(f"共处理 {len(list(source.glob(pattern)))} 个文件")# 使用示例
process_files("data/source", "data/processed", "*.txt")

6. 安全路径操作函数

from pathlib import Path
import osdef safe_file_operation(file_path, operation, *args, **kwargs):"""安全执行文件操作,防止路径遍历攻击"""# 获取当前工作目录的绝对路径base_path = Path.cwd().resolve()# 解析目标路径并检查是否在安全范围内target_path = Path(file_path).resolve()if not target_path.is_relative_to(base_path):raise ValueError("路径超出安全范围,可能包含目录遍历攻击")# 执行操作try:return operation(target_path, *args, **kwargs)except FileNotFoundError as e:print(f"文件未找到: {file_path}")raise eexcept PermissionError as e:print(f"权限错误: {file_path}")raise e# 使用示例
def read_file_safe(file_path):return safe_file_operation(file_path, Path.read_text)content = read_file_safe("data/file.txt")

八、常见问题与解决

1. 为什么在Windows上使用pathlib时路径显示为反斜杠?

  • 在Python字符串中,反斜杠是转义字符
  • 解决方案:使用原始字符串或正斜杠
# 正确方式
p = Path(r"C:\Users\user")  # 原始字符串
p = Path("C:/Users/user")   # 正斜杠# 错误方式
p = Path("C:\Users\user")   # 会被解释为C:Usersuser

2. 如何处理路径中的空格和特殊字符?

  • pathlib会自动处理特殊字符,无需额外处理
p = Path("my folder/file with spaces.txt")
# 无需额外转义,pathlib会正确处理

3. 如何在不同系统间共享路径?

  • 使用pathlib的as_posix()方法
path = Path("data/file.txt")
posix_path = path.as_posix()  # 'data/file.txt' (Unix风格)
windows_path = path.as_posix().replace("/", "\\")  # 'data\file.txt' (Windows风格)

九、总结与建议

  1. 新项目首选pathlib:它是Python 3.4+的标准库,提供了面向对象的路径处理方式,代码更简洁、可读性更好。
  2. 避免硬编码路径分隔符:使用os.path.join()或pathlib的/运算符,避免使用硬编码的’/‘或’'。
  3. 使用glob进行模式匹配:特别是当需要遍历特定模式的文件时,glob与pathlib结合使用效果最佳。
  4. 处理路径安全:在处理用户输入的路径时,使用.resolve()确保路径的安全性,避免目录遍历攻击。
  5. 考虑EAFP风格:Python社区推荐EAFP(先尝试,再捕获异常)风格,比LBYL(先检查,再操作)更简洁。
  6. 逐步迁移:如果维护旧代码,可以逐步将os.path代码迁移到pathlib,提高代码质量和可维护性。
http://www.dtcms.com/a/483950.html

相关文章:

  • 男人女人做羞羞事网站如皋网站建设招标
  • 在线相册jsp网站开发与设计徐州泰安抖音代运营
  • 网站seo优化步骤给我一个用c 做的网站
  • 重庆建设造价信息网站深圳带停机坪的别墅
  • 2026计算机毕设选题推荐:基于SpringBoot和Vue的电动车租赁平台系统(附源码和数据库)
  • 建湖做网站需要多少钱wordpress缓存图片
  • 济宁网站建设 中企动力临沂wordpress阻止访问
  • 南京建设网站要多少钱手机网站需要域名吗
  • 基于成功率的自适应差分进化 L-SRTDE 用于 CEC 2024 竞赛
  • 企业 办公 网站模板下载企业网站制作步骤
  • 网站建设大致分哪几块天津网站开发公司
  • 怎样查网站备案人的联系方式网站开发自学时间
  • 网站系统平台建设个人网站主页
  • 基于springboot的民谣网站的设计与实现
  • Linux系统新建用户登录只显示$简陋提示符 ,不显示用户名、主机名字、当前目录...
  • 阿里云网站托管公司软件网站建设
  • 安装网站时出现dir网站的常用技术有哪些
  • 十字链表的构建和操作
  • 中山做网站的公司哪家好佛山100强企业名单
  • 广州网站建设+美词有哪些网站做的好处
  • 网站查询功能怎么做php网页设计完整代码
  • Efficient Multi-Scale Attention Module with Cross-Spatial Learning 学习笔记
  • 国内专门做情侣的网站商城广州市建设工程信息管理平台
  • 游仙移动网站建设有意义网站
  • 小红书MCP AI自动工作流
  • QPSK信号载波同步技术---四相Costas 环法
  • android开发和网站开发wordpress对比phpcms
  • [嵌入式系统-111]:瑞芯微RK3588芯片
  • 广东顺德网站建设在线买房网站建设 方案
  • 深入剖析 std::map 的红黑树实现机制