查看: 308|回复: 0

Python目录文件路径:os.path与pathlib实战避坑

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
在Python开发中,目录与文件路径处理几乎是所有项目的刚需:读取配置、遍历文件夹、批量处理文件、日志路径配置、项目路径定位都会涉及。Python提供两套核心路径体系:os.path(函数式写法,兼容Python2/3)和pathlib(面向对象写法,Python3.4+新增)。下面按基础概念、os.path核心用法、pathlib核心用法、选型、高频避坑和批量案例进行整理。

一、路径基础:绝对路径与相对路径
绝对路径从系统根目录开始,唯一指向一个文件或目录。Windows以盘符开头,Linux/macOS以/开头。相对路径相对于当前运行脚本的工作目录,工作目录变化时会失效。跨平台分隔符方面,Windows默认使用反斜杠,Linux/macOS默认使用正斜杠。核心原则是不要手动写死路径分隔符,应通过Python内置方法自动适配,避免跨平台报错。

二、os.path模块核心操作
os.path采用函数式写法,传入路径字符串即可操作,兼容Python2/3,适合老旧项目维护。

基础路径信息获取:
  1. import os
  2. test_path = 'data/test_file.txt'
  3. print('当前工作目录:', os.getcwd())
  4. abs_path = os.path.abspath(test_path)
  5. print('绝对路径:', abs_path)
  6. dir_path = os.path.dirname(abs_path)
  7. print('所在目录:', dir_path)
  8. file_name = os.path.basename(abs_path)
  9. print('文件名称:', file_name)
  10. raw_path = './data//test_file.txt'
  11. norm_path = os.path.normpath(raw_path)
  12. print('规范化路径:', norm_path)
  13. real_path = os.path.realpath(test_path)
  14. print('物理真实路径:', real_path)
复制代码

路径拼接使用os.path.join():
  1. import os
  2. path1 = os.path.join('project', 'data', 'logs', 'run.log')
  3. print('基础拼接结果:', path1)
  4. path2 = os.path.join('project', '/usr/local', 'file.txt')
  5. print('绝对路径覆盖拼接:', path2)
  6. path3 = os.path.join('data', '', 'test.txt')
  7. print('空参数拼接:', path3)
复制代码
os.path.join()会自动适配系统分隔符,自动忽略空字符串;如果后面传入绝对路径,会覆盖前面的路径。拼接多级路径时不要首尾加分隔符,交给join方法处理。

路径类型判断与存在性校验:
  1. import os
  2. test_path = 'data/test_file.txt'
  3. dir_path = 'data'
  4. print('路径是否存在:', os.path.exists(test_path))
  5. print('是否为文件:', os.path.isfile(test_path))
  6. print('是否为目录:', os.path.isdir(dir_path))
  7. print('是否为绝对路径:', os.path.isabs(test_path))
  8. print('是否为软链接:', os.path.islink(test_path))
复制代码

目录遍历os.walk():
  1. import os
  2. def traverse_dir(root_path):
  3.     for dirpath, dirnames, filenames in os.walk(root_path):
  4.         print(f'当前遍历目录:{dirpath}')
  5.         for dir_name in dirnames:
  6.             print(f'子目录:{os.path.join(dirpath, dir_name)}')
  7.         for file_name in filenames:
  8.             file_full_path = os.path.join(dirpath, file_name)
  9.             print(f'文件路径:{file_full_path}')
  10. traverse_dir('./')
复制代码
os.walk()递归遍历所有子目录和文件,返回当前目录、子目录列表、文件列表三元组。

三、pathlib模块核心操作
pathlib从Python3.4开始提供,采用面向对象写法,路径本身是Path对象,支持/运算符拼接和链式调用,代码更简洁。

Path对象初始化与拼接:
  1. from pathlib import Path
  2. p1 = Path('data/test.txt')
  3. p2 = Path('/usr/local/python')
  4. p3 = Path.cwd()
  5. p4 = Path.home()
  6. print('相对路径对象:', p1)
  7. print('当前工作目录:', p3)
  8. print('用户家目录:', p4)
  9. base_path = Path('project')
  10. full_path = base_path / 'data' / 'logs' / 'run.log'
  11. print('路径拼接结果:', full_path)
  12. abs_path = Path.cwd() / 'config' / 'setting.ini'
  13. print('绝对拼接路径:', abs_path)
复制代码

路径属性解析与判断:
  1. from pathlib import Path
  2. p = Path('data/test_image.jpg')
  3. print('完整路径:', p)
  4. print('所在父目录:', p.parent)
  5. print('多级父目录:', p.parents[0], p.parents[1])
  6. print('完整文件名(含后缀):', p.name)
  7. print('纯文件名(无后缀):', p.stem)
  8. print('文件后缀:', p.suffix)
  9. print('所有后缀:', p.suffixes)
  10. print('规范化绝对路径:', p.resolve())
  11. print('路径是否存在:', p.exists())
  12. print('是否是文件:', p.is_file())
  13. print('是否是目录:', p.is_dir())
  14. print('是否是绝对路径:', p.is_absolute())
  15. print('是否是软链接:', p.is_symlink())
复制代码

目录创建、删除与遍历:
  1. from pathlib import Path
  2. dir_path = Path('project/logs/2026')
  3. dir_path.mkdir(parents=True, exist_ok=True)
  4. print('目录创建完成')
  5. root = Path('./')
  6. print('===== 单层目录遍历 =====')
  7. for item in root.iterdir():
  8.     if item.is_file():
  9.         print(f'文件:{item.name}')
  10.     else:
  11.         print(f'目录:{item.name}')
  12. print('===== 递归遍历所有Python文件 =====')
  13. for py_file in root.rglob('*.py'):
  14.     print(f'Python文件:{py_file.resolve()}')
  15. for txt_file in root.glob('*.txt'):
  16.     print(f'文本文件:{txt_file}')
复制代码
mkdir的parents=True用于递归创建多级父目录,exist_ok=True表示目录已存在时不报错。rmdir仅能删除空目录。

resolve、absolute与expanduser:
  1. from pathlib import Path
  2. p = Path('documents/../file.txt')
  3. print(p.resolve())
  4. p = Path('/nonexistent/path')
  5. print(p.resolve(strict=False))
  6. p = Path('~/documents').expanduser()
  7. print(p)
复制代码
resolve()会解析符号链接并返回绝对路径,默认要求路径存在;strict=False在Python3.6+下路径不存在也不报错。absolute()不解析符号链接,也不要求路径存在。Path不会自动展开~,需要使用expanduser()。

Path常用属性和方法:
  1. from pathlib import Path
  2. p = Path('/home/user/docs/report.txt')
  3. print(p.name)
  4. print(p.stem)
  5. print(p.suffix)
  6. print(p.suffixes)
  7. print(p.parent)
  8. print(p.parents)
  9. print(p.parts)
  10. print(p.anchor)
  11. print(p.as_uri())
  12. print(p.exists())
  13. print(p.is_file())
  14. print(p.is_dir())
  15. print(p.is_symlink())
  16. print(p.is_absolute())
  17. new = p.with_name('summary.txt')
  18. new = p.with_stem('data')
  19. new = p.with_suffix('.md')
  20. print(new)
  21. base = Path('/home/user')
  22. print(p.relative_to(base))
  23. content = Path('file.txt').read_text(encoding='utf-8')
  24. Path('out.txt').write_text('Hello', encoding='utf-8')
  25. data = Path('file.bin').read_bytes()
  26. Path('out.bin').write_bytes(data)
  27. Path('new_dir').mkdir(parents=True, exist_ok=True)
  28. Path('file.txt').unlink(missing_ok=True)
  29. Path('dir').rmdir()
  30. Path('link').symlink_to('target')
  31. Path('link').readlink()
复制代码
relative_to在路径不匹配时会报ValueError。

四、os.path与pathlib选型
os.path:函数式,零散繁琐,兼容Python2/3,使用os.path.join拼接,os.walk遍历。
pathlib:面向对象,链式简洁,仅Python3.4+,使用/运算符拼接,属性直接获取,iterdir/glob/rglob遍历更简洁,跨平台适配更好。
结论:新项目、Python3环境优先使用pathlib;老旧项目、需要兼容Python2时使用os.path;混合场景可以把Path对象转为字符串,兼容旧版路径函数。

五、高频场景与避坑
项目根目录精准定位:
  1. from pathlib import Path
  2. FILE_PATH = Path(__file__).resolve()
  3. ROOT_PATH = FILE_PATH.parent
  4. CONFIG_PATH = ROOT_PATH / 'config' / 'setting.ini'
  5. print('项目根目录:', ROOT_PATH)
  6. print('配置文件路径:', CONFIG_PATH)
复制代码
基于脚本文件定位项目根目录,不受运行目录影响。

路径字符串与Path对象互转:
  1. from pathlib import Path
  2. str_path = 'data/test.txt'
  3. path_obj = Path(str_path)
  4. new_str_path = str(path_obj)
  5. print('转换后字符串路径:', new_str_path)
复制代码

避坑总结:
1 禁止手动写死分隔符,不要用反斜杠或正斜杠拼接路径,交给系统方法自动适配。
2 创建多级目录必须加parents=True,否则多级嵌套目录会报错。
3 相对路径失效时用__file__定位,避免使用os.getcwd()定位项目路径,工作目录可动态切换。
4 删除目录优先判断空目录,pathlib的rmdir仅支持空目录,非空目录需要递归删除。

六、批量修改文件后缀案例
  1. from pathlib import Path
  2. def batch_rename_suffix(folder_path, old_suffix, new_suffix):
  3.     folder = Path(folder_path)
  4.     for file in folder.rglob(f'*{old_suffix}'):
  5.         if file.is_file():
  6.             new_file_name = file.stem + new_suffix
  7.             new_file_path = file.parent / new_file_name
  8.             file.rename(new_file_path)
  9.             print(f'修改成功:{file.name} -> {new_file_name}')
  10. if __name__ == '__main__':
  11.     batch_rename_suffix('./', '.txt', '.bak')
复制代码

以上内容覆盖Python目录与文件路径处理的主要API、参数含义、调用方式和避坑点。实际开发中可根据Python版本和项目兼容要求,在os.path与pathlib之间选择。
回复

使用道具 举报

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

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

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

官方核心成员

关注微信公众号

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

GMT+8, 2026-10-12 13:31 , Processed in 0.041558 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部