查看: 153|回复: 3

Python目录操作完全指南 os与pathlib实战用法

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在 Python 开发中,目录操作既是基础也是高频场景。无论是要读取配置、遍历日志,还是管理项目文件,都绕不开获取当前目录、列出目录内容、递归遍历等操作。Python 标准库提供了 os 和 pathlib 两个核心模块,前者是传统函数式接口,后者是 Python 3.4+ 引入的面向对象路径库。对于新项目,pathlib 更直观、更 Pythonic,但 os 模块在处理系统级交互时依然不可替代。本文从实际开发角度出发,系统梳理这两个模块在目录获取与操作中的典型用法。

获取当前工作目录是很多文件操作的第一步。os.getcwd() 返回字符串,而 pathlib.Path.cwd() 返回 Path 对象,后者可以直接调用 .parent、.joinpath() 等方法。示例代码如下:
  1. import os
  2. current_dir = os.getcwd()
  3. print(f"当前工作目录: {current_dir}")
  4. from pathlib import Path
  5. current_path = Path.cwd()
  6. print(f"当前工作目录: {current_path}")
  7. print(f"上级目录: {current_path.parent}")
复制代码

列出目录内容时,os.listdir(path) 仅返回文件名组成的字符串列表,不会包含路径信息。若要判断条目是文件还是目录,还需要配合 os.path.isdir() 或 os.path.isfile()。pathlib.Path.iterdir() 则返回 Path 对象生成器,每个条目自带完整路径,可以直接调用 .is_file()、.is_dir()、.name 等属性,更适合做进一步处理。
  1. import os
  2. path = "./data"
  3. try:
  4.     entries = os.listdir(path)
  5.     for entry in entries:
  6.         print(entry)
  7. except FileNotFoundError:
  8.     print(f"目录 '{path}' 不存在")
  9. from pathlib import Path
  10. path_obj = Path("./data")
  11. if path_obj.exists() and path_obj.is_dir():
  12.     for entry in path_obj.iterdir():
  13.         print(f"{entry.name} - {'目录' if entry.is_dir() else '文件'}")
复制代码

递归遍历目录树时,os.walk() 是经典方案,它为每个目录返回 (dirpath, dirnames, filenames) 三元组。pathlib 则推荐使用 rglob() 和 glob()。rglob(pattern) 会递归匹配所有层级,glob(pattern) 仅匹配当前目录。例如递归查找所有 .py 文件:
  1. import os
  2. for dirpath, dirnames, filenames in os.walk("./project"):
  3.     print(f"目录: {dirpath}")
  4.     print(f"子目录: {dirnames}")
  5.     print(f"文件: {filenames}")
  6.     print("-" * 40)
  7. from pathlib import Path
  8. project = Path("./project")
  9. py_files = list(project.rglob("*.py"))
  10. for f in py_files:
  11.     print(f)
复制代码

获取绝对路径也很关键。相对路径容易受脚本启动位置影响,使用绝对路径更可靠。os.path.abspath() 可以把相对路径转为绝对路径;pathlib 的 resolve() 不仅返回绝对路径,还会解析符号链接。
  1. import os
  2. abs_path = os.path.abspath("./docs/readme.txt")
  3. print(abs_path)
  4. from pathlib import Path
  5. abs_path2 = Path("./docs/readme.txt").resolve()
  6. print(abs_path2)
复制代码

在操作前检查路径是否是目录,可以提前避免很多错误。os.path.isdir() 接收字符串,Path.is_dir() 是实例方法,两者注意区分。

创建目录时,os.makedirs() 和 Path.mkdir() 都支持递归创建多级目录。os.makedirs() 需要设置 exist_ok=True 才能避免目录已存在时抛异常;Path.mkdir() 需要设置 parents=True 才能递归创建父目录,同时配合 exist_ok=True 避免冲突。删除目录方面,os.rmdir() 只能删除空目录,非空目录必须用 shutil.rmtree(),该操作不可逆,要特别谨慎。
  1. import os
  2. from pathlib import Path
  3. import shutil
  4. os.makedirs("./parent/child/grandchild", exist_ok=True)
  5. Path("./deep/nested/path").mkdir(parents=True, exist_ok=True)
  6. os.rmdir("./empty_dir")  # 仅空目录
  7. shutil.rmtree("./dir_with_content")  # 递归删除,危险!
复制代码

路径拼接与分解在跨平台开发中尤为重要。直接使用字符串拼接“/”在 Windows 上可能出错。os.path.join() 能根据操作系统自动选择分隔符,pathlib 则直接用“/”运算符重载,更为优雅。
  1. import os
  2. full_path = os.path.join("/home/user", "docs", "file.txt")
  3. print(full_path)
  4. from pathlib import Path
  5. base = Path("/home/user")
  6. full_path2 = base / "docs" / "file.txt"
  7. print(full_path2)
  8. print(f"父目录: {full_path2.parent}")
  9. print(f"文件名: {full_path2.name}")
  10. print(f"后缀: {full_path2.suffix}")
  11. print(f"无后缀文件名: {full_path2.stem}")
复制代码

实战中,统计目录下文件类型分布是常见需求。通过 rglob("*") 遍历全部条目,筛选出文件,再按后缀名分组计数,很容易实现:
  1. from pathlib import Path
  2. from collections import Counter
  3. def analyze_directory(directory_path):
  4.     path = Path(directory_path)
  5.     if not path.exists() or not path.is_dir():
  6.         print(f"错误: '{directory_path}' 不是有效目录")
  7.         return
  8.     extensions = []
  9.     for item in path.rglob("*"):
  10.         if item.is_file():
  11.             ext = item.suffix.lower() or "无后缀"
  12.             extensions.append(ext)
  13.     if not extensions:
  14.         print("该目录下未找到文件。")
  15.         return
  16.     counter = Counter(extensions)
  17.     print(f"目录 '{directory_path}' 下的文件类型统计:")
  18.     for ext, count in counter.most_common():
  19.         print(f"  {ext}: {count} 个文件")
  20. analyze_directory("./my_project")
复制代码

总结几点最佳实践:优先使用 pathlib,尤其在新项目中,它封装了路径对象,方法链式调用更清晰;文件系统操作必须处理异常,如权限不足、路径不存在,用 try/except 包裹关键步骤;脚本中涉及关键路径时尽量使用绝对路径或 resolve(),避免工作目录变化导致找不到文件;递归操作如 rglob() 和 shutil.rmtree() 要反复确认目标路径,防止误删;跨平台项目统一使用 os.path.join() 或 pathlib 的“/”操作符,让代码在 Windows 和 Linux/macOS 上都能正确处理路径分隔符。

掌握这些目录操作细节后,后续编写文件处理脚本、日志分析工具或自动化构建流程都会更加得心应手。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python目录操作完全指南 os与pathlib实战用法

这篇文章很实用,正好最近在折腾文件批量处理,os 和 pathlib 的对比讲得很清楚。以前习惯用 os,现在感觉 pathlib 的链式操作确实更顺手,特别是 `Path.cwd()` 和 `/` 拼接路径那部分,代码看起来干净多了。递归遍历用 `rglob` 也比手动 `os.walk` 省事,感谢分享!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python目录操作完全指南 os与pathlib实战用法

这篇指南写得很清楚,正好最近在整理项目文件结构,os 和 pathlib 的对比部分特别实用。pathlib 的 `/` 运算符拼接路径确实比 `os.path.join` 优雅不少,不过 Windows 上 `resolve()` 解析符号链接的行为有时候会和预期不太一样,不知道楼主有没有遇到过?另外 `rglob` 在目录特别大时性能怎么样,有没有什么优化建议?
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python目录操作完全指南 os与pathlib实战用法

干货满满,正好最近在从 os 迁移到 pathlib,这篇把两者的差异和适用场景讲得很清楚。尤其是 rglob 递归查找和 Path.resolve() 解析符号链接这部分,实际项目里太常用了。另外提醒一下新手朋友,shutil.rmtree 真的慎用,删之前最好先打印确认路径,别问我是怎么知道的……收藏了,以后当速查手册用。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-8-23 16:30 , Processed in 0.020586 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部