用 Python pathlib 替代 os.path 写跨平台脚本
很多跨平台脚本一开始都写得很顺:本地在 Windows 上跑通,放到 Linux 服务器上却因为路径分隔符、大小写、换行和相对路径问题接连报错。os.path 当然能用,但它本质上是把路径当字符串处理,拼接、判断、遍历都要你自己把规则记全。Python 3.4 之后的标准库 pathlib 把路径变成对象,写法更直观,也更容易一次写对、处处运行。下面用几个日常场景说明怎么替换。
一、拼接路径:用 / 代替字符串加法
以前常见写法是 os.path.join(base, ‘data’, ‘report.csv’),在 Windows 上会得到反斜杠,在 Linux 上是正斜杠,混用字符串拼接时最容易漏分隔符或多写一个。用 Path 可以直接写:
from pathlib import Path
base = Path('data')
report = base / 'report.csv'
print(report)
斜杠运算符在这里不是除法,而是 Path 重载的路径拼接。好处是代码读起来就是目录结构本身,而且你不用再判断 base 末尾有没有斜杠。需要转成字符串传给只接受 str 的旧接口时,用 str(report) 即可。
二、判断与读取:方法名就是意图
检查文件是否存在、是不是目录、读文本,pathlib 都是一句话:
from pathlib import Path
p = Path('config.json')
if p.exists() and p.is_file():
text = p.read_text(encoding='utf-8')
print(text[:100])
对比 os.path.exists、os.path.isfile 再加 open 的组合,Path 的版本少了一次打开文件的样板代码。写文件同样直接:p.write_text(‘hello’, encoding=‘utf-8’)。注意编码一定要显式写 utf-8,否则 Windows 默认编码可能是 GBK,中文很容易在换机器后乱码。
三、遍历与筛选:glob 比 walk 更顺手
要找出某个目录下所有 Python 文件,os.walk 需要三层循环和条件判断,而 Path.glob 一行就能表达:
from pathlib import Path
for py_file in Path('src').rglob('*.py'):
print(py_file)
rglob 表示递归查找,glob 只查当前目录。配合 suffix、stem、name 这些属性,筛选逻辑也很清晰:py_file.suffix 是扩展名,py_file.stem 是不带扩展名的文件名,py_file.parent 是所在目录。
四、一个可直接用的小例子:归档日志
把当前目录下所有 .log 文件按日期归档到 logs 目录,是典型的跨平台脚本:
from pathlib import Path
import shutil
src = Path('.')
dst = Path('logs')
dst.mkdir(parents=True, exist_ok=True)
for log in src.glob('*.log'):
shutil.copy2(log, dst / log.name)
print(f'已归档:{log} -> {dst / log.name}')
mkdir 的 parents=True 相当于 mkdir -p,exist_ok=True 表示目录已存在也不报错。这两点在脚本重复运行时特别重要。
五、注意事项:不是所有地方都能无脑替换
第一,Path 对象在 Windows 上默认是 WindowsPath,在 Linux 上是 PosixPath,跨系统硬编码盘符如 C:\data 在 Linux 上没有意义,尽量用相对路径或通过环境变量、配置文件传入根目录。第二,路径比较不要只比字符串,大小写和符号链接会让字符串不同但实际指向同一文件,必要时用 resolve() 规范化后再比较,但要注意 resolve 会解析符号链接。第三,路径里有空格、中文时不要自己加引号,subprocess 等接口接受 Path 或字符串列表时,交给库去处理转义更安全。第四,Path(‘/tmp’) / ‘/etc’ 这种写法中,如果右边是绝对路径,结果会直接变成右边的绝对路径,这不是 bug,而是 pathlib 的规则,拼接用户输入前要先检查。
结语
把 os.path 换成 pathlib,并不是为了追新,而是把路径从字符串升级为有语义的对象:拼接用 /,判断用 exists 和 is_file,遍历用 glob,读写用 read_text 和 write_text。先从新脚本开始用,旧脚本在改动相关路径逻辑时顺手迁移,跨平台问题会少很多。
- 点赞
- 收藏
- 关注作者
评论(0)