
pathlib是Python 3.4+内置的强大路径处理库,相比传统的os.path,它以面向对象的方式提供更直观、易读且功能全面的路径操作方法,如路径拼接、文件读写、目录创建与遍历等。使用pathlib能显著简化文件和目录管理代码,减少错误和冗余,是现代Python开发中更推荐使用的路径处理工具。
1. 初始化与基本操作
from pathlib import Path
# 创建相对路径对象
current_file = Path('example.py')
# 创建绝对路径对象(跨平台)
home_dir = Path.home()
project_dir = home_dir / 'projects' / 'my_project'file_path = Path('data/reports/sales_2023.csv')
file_path.name # 'sales_2023.csv'
file_path.stem # 'sales_2023'
file_path.suffix # '.csv'
file_path.parent # PosixPath('data/reports')
file_path.parts # ('data', 'reports', 'sales_2023.csv')
file_path.absolute() # 解析为绝对路径# 推荐:运算符 /
config_path = Path('config') /'settings'/'dev.yaml'
# joinpath
log_path = Path('logs').joinpath('app', 'error.log')
# 动态多段
parts = ['data', '2023', 'Q3', 'report.xlsx']
report_path = Path.cwd().joinpath(*parts)file_path = Path('src/utils/__init__.py')
file_path.exists() # 是否存在
file_path.is_file() # 文件
file_path.is_dir() # 目录
file_path.resolve() # 绝对路径(解析符号链接)
file_path.as_uri() # file:// URI# 文本
config_file = Path('config/settings.ini')
config_file.write_text('[DEFAULT]\nlanguage=en\n', encoding='utf-8')
content = config_file.read_text(encoding='utf-8')
# 二进制
image_path = Path('static/images/logo.png')
binary_data = image_path.read_bytes()
# 追加写入
withconfig_file.open('a', encoding='utf-8') asf:
f.write('\n[Database]\nhost=localhost')# 递归创建
data_dir = Path('data/raw/2023')
data_dir.mkdir(parents=True, exist_ok=True)
# 一级遍历
foriteminPath('src').iterdir():
ifitem.is_file():
print(f"文件: {item.name}")
elifitem.is_dir():
print(f"目录: {item.name}")
# 递归 glob
forpy_fileinPath('.').rglob('*.py'):
print(py_file.absolute())(Path('data')
.mkdir(exist_ok=True)
.joinpath('processed')
.mkdir(exist_ok=True)
.joinpath('results.json')
.write_text('{"status": "success"}', encoding='utf-8'))fromdatetimeimportdatetime
log_file = Path('/var/log/app.log')
stats = log_file.stat()
print(f"大小: {stats.st_size / 1024:.2f} KB")
print(f"修改时间: {datetime.fromtimestamp(stats.st_mtime)}")
print(f"权限: {oct(stats.st_mode)[-3:]}")forreportinPath('reports').glob('2023_Q[1-4]_*.xlsx'):
quarter = report.stem.split('_')[1]
print(f"处理第 {quarter} 季度报告: {report}")fortxt_fileinPath('docs').glob('*.txt'):
new_name = txt_file.with_suffix('.md')
txt_file.rename(new_name)
print(f"重命名: {txt_file} -> {new_name}")config_dir = Path.home() /'.config'/'my_app'
config_files = list(config_dir.glob('*.conf'))
settings = {}
forconf_fileinconfig_files:
forlineinconf_file.read_text(encoding='utf-8').splitlines():
if'='inline:
key, value = line.split('=', 1)
settings[key.strip()] = value.strip()importtempfile
frompathlibimportPath
defprocess_data(csv_path: Path):
"""占位:业务处理逻辑"""
pass
withtempfile.TemporaryDirectory() astmp:
tmp_path = Path(tmp)
tmp_file = tmp_path/'temp_data.csv'
tmp_file.write_text("id,name,value\n1,test,100", encoding='utf-8')
process_data(tmp_file)
# 退出 with 块后目录自动删除importos
defload_resource(relative_path: str) ->str:
base_path = Path(__file__).parent
resource_path = (base_path/relative_path).resolve()
returnresource_path.read_text(encoding='utf-8')importyaml
defload_config(env: str) ->dict:
config_path = Path("config") /env/"settings.yaml"
ifnotconfig_path.exists():
raiseFileNotFoundError(config_path)
backup = config_path.with_suffix('.yaml.bak')
backup.write_text(config_path.read_text(encoding='utf-8'), encoding='utf-8')
returnyaml.safe_load(config_path.read_text(encoding='utf-8'))importtime
fromdatetimeimportdatetime
defarchive_old_logs(log_dir: Path, days: int = 30):
cutoff = time.time() -days*86400
archive_dir = log_dir/"archives"
archive_dir.mkdir(exist_ok=True)
forlog_fileinlog_dir.glob("*.log"):
iflog_file.stat().st_mtime<cutoff:
ts = datetime.fromtimestamp(log_file.stat().st_mtime).strftime('%Y%m%d')
new_name = f"{log_file.stem}_{ts}{log_file.suffix}"
log_file.rename(archive_dir/new_name)defsetup_project_structure(base_dir: Path):
dirs = [
base_dir/"src",
base_dir/"tests",
base_dir/"docs",
base_dir/"data/raw",
base_dir/"data/processed",
base_dir/"logs",
]
fordindirs:
d.mkdir(parents=True, exist_ok=True)
(d/".gitkeep").touch()
readme = base_dir/"README.md"
ifnotreadme.exists():
readme.write_text("# Project Documentation\n\n...", encoding='utf-8')importos
defsecure_delete(file_path: Path, passes: int = 3):
ifnotfile_path.is_file():
raiseValueError(f"{file_path} 不是文件")
size = file_path.stat().st_size
withfile_path.open('br+') asf:
for_inrange(passes):
f.seek(0)
f.write(os.urandom(size))
f.flush()
os.fsync(f.fileno())
file_path.unlink()优势 | 说明 |
|---|---|
面向对象 | 路径即对象,属性与方法一目了然 |
跨平台 | Windows、macOS、Linux 无缝切换 |
安全 | 避免手动拼接字符串带来的分隔符错误 |
功能丰富 | 读写、遍历、权限、元数据一站式解决 |
pathlib提供了现代化、面向对象的路径操作方法,将 os.path 时代散落在各处的功能收拢到统一、优雅的 API 中,它能显著提高代码的可读性和可维护性,同时减少路径相关的常见错误。
“无他,惟手熟尔”!有需要就用起来。
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!