Python:用 pathlib 扫一下目录,比字符串拼路径少踩点

40 次浏览4 条回复

写脚本处理一批文件时,pathlib 比手动拼路径舒服一点,尤其是跨平台路径分隔符不用自己管。

环境:Python 3.8+。可以建个小目录试:

mkdir pathlib-demo && cd pathlib-demo
printf 'hello\n' > a.txt
printf 'skip\n' > b.log
printf 'world\n' > c.txt

再建一个 scan.py:

from pathlib import Path

root = Path('.')
for path in sorted(root.glob('*.txt')):
    print(path.name, '=>', path.read_text(encoding='utf-8').strip())

运行:

python scan.py

大概会看到:

a.txt => hello
c.txt => world

这种写法适合本地小脚本。要递归扫子目录可以把 glob('*.txt') 换成 rglob('*.txt'),不过目录很大时最好先加一点过滤,别一口气扫太多。

这个写法挺适合顺手脚本。

我一般还会多加一层 is_file(),避免目录名刚好匹配模式,或者后面有人放了奇怪的条目:

from pathlib import Path

for path in sorted(Path('.').glob('*.txt')):
    if not path.is_file():
        continue
    print(path.name, path.read_text(encoding='utf-8').strip())

小目录里区别不大,但脚本以后被拿去扫真实目录时会稳一点。

还有个小细节:如果用 rglob 扫子目录,输出完整路径有时会太长,可以按根目录转成相对路径再打印。

from pathlib import Path

root = Path('src')
for path in sorted(root.rglob('*.py')):
    if path.is_file():
        print(path.relative_to(root))

这样日志里看到的是 pkg/app.py 这种形式,后面拿去做清单或者对比文件列表会清爽一点。

再补一个边角:如果目录里文件名来自不同系统,后缀大小写可能会混着来,比如 .TXT。这时候可以别只靠 glob('*.txt'),先扫一层再判断:

from pathlib import Path

for path in sorted(Path('.').iterdir()):
    if path.is_file() and path.suffix.lower() == '.txt':
        print(path.name)

文件不多的时候这样挺直观。目录很大再考虑更细的过滤。

还有一种小坑是:Path 对象现在大多数标准库都能直接吃,但有些第三方库老接口只收字符串。

遇到这种就别在前面一路手动拼字符串,可以最后一刻再转:

from pathlib import Path

path = Path('data') / 'input.txt'

# 老接口如果不认 Path,再这样传
legacy_api(str(path))

这样前面还是能保留 / 拼路径、suffix、stem 这些方便用法。感觉比一开始就 str(Path(...)) 清楚一点。