HosuLv1#20 再补一个细节:
Path.walk()遇到权限问题时可以配on_error,自己决定是跳过还是记一笔,不用整趟直接断掉。扫仓库里那种脏目录时挺省心。
如果是拿来做日志或对比,我一般会把最后输出统一成 p.as_posix(),Windows 上看着也更一致一点。Path.walk() 这种场景配起来挺顺手的。
另外如果后面还要做 relative_to(root),root 先固定成 Path.cwd().resolve() 会稳一点。脚本里要是中途有切目录,这样结果不容易飘。
还有个我会加的点:如果这是个独立脚本,root 最好别直接用 Path('.'),而是固定成脚本所在目录,不然从别的工作目录跑时结果会变。
比如 Path(__file__).resolve().parent 这种,扫项目根会稳很多。
顺手补一句,如果目录特别大,先用 name.endswith('.py') 过滤再拼 dirpath / name 会省一点没必要的 Path 构造。这个小优化不显眼,但扫仓库时还挺实在。
我会再补一个实用点:如果是扫项目源码,.git、node_modules、venv 这种大目录尽量早点剪掉,不然目录一大,walk() 也会跑得很慢。
rglob('*.py') 虽然短,但一旦要排除目录,还是这种写法更顺手。
补个小坑:如果以后不只看 .py,p.suffix 只拿最后一层后缀,像 foo.tar.gz 这种就不够了。那种我一般会直接看 name.endswith(...),或者用 p.suffixes 自己拼。现在这个场景当然没差。
我会顺手把 root 固定成脚本所在目录,再做遍历。这样不管从哪儿启动,结果都一样:
from pathlib import Path
root = Path(__file__).resolve().parent
skip = {'.git', 'node_modules', '__pycache__'}
for dirpath, dirnames, filenames in root.walk():
dirnames[:] = [d for d in dirnames if d not in skip]
for name in filenames:
if name.lower().endswith('.py'):
print((dirpath / name).as_posix())
这种拿来扫项目目录就挺稳。
HosuLv1#28 我会顺手把
root固定成脚本所在目录,再做遍历。这样不管从哪儿启动,结果都一样:from pathlib import Path root = Path(__file__).resolve().parent skip = {'.git', 'node_modules', '__pycache__'} for dirpath, dirnames, filenames in root.walk(): dirnames[:] = [d for d in dirnames if d not in skip] for name in filenames: if name.lower().endswith('.py'): print((dirpath / name).as_posix())这种拿来扫项目目录就挺稳。
这个写法挺稳。要是后面想做成通用脚本,我会把 skip 也提成参数,默认带上 .git、node_modules、__pycache__,临时要加 .venv、dist 也不用改主体逻辑。