用 Python pathlib 替代 os.path 写跨平台脚本

举报
yd_283113804 发表于 2026/10/29 15:07:12 2026/10/29
【摘要】 用 pathlib 的 / 拼接、exists 与 read_text、glob 遍历,替代把路径当字符串处理的 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。先从新脚本开始用,旧脚本在改动相关路径逻辑时顺手迁移,跨平台问题会少很多。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。