高效遍历目录应先收集路径再批量stat,用pathlib.path替代os.walk,scandir性能更优;大小排序前转人类可读单位,静默处理permissionerror/filenotfounderror,注意windows编码与路径长度问题。

用 os.walk 遍历目录时,别直接 os.stat 每个文件
常见错误是边遍历边调 os.stat,尤其在有成千上万个文件的目录里,I/O 开销大、速度慢,还容易卡住。真正高效的做法是:先收集所有文件路径,再批量获取大小(或用生成器避免内存爆炸)。
- 优先用
pathlib.Path替代os.walk+os.path.join,代码更简洁、路径处理更安全 - 对每个
Path对象,用.stat().st_size获取大小,不是.size()(后者不存在) - 如果目录极深或文件极多,改用
os.scandir,它比os.walk少一次系统调用,性能高 20%–50%
按大小排序前,记得把字节转成人类可读单位
直接输出字节数没人看得懂,但别手写除法链式判断(比如 if size > 1024**3: ...),容易漏边界、难维护。Python 标准库没内置,但一行 humanize 包就能搞定 —— 不过得先装:pip install humanize。
- 不用第三方?自己写个简版函数,核心逻辑是循环除以 1024,用列表存单位
["B", "KB", "MB", "GB", "TB"] - 注意:Windows 下
os.stat().st_size对符号链接返回的是链接本身大小(通常几十字节),不是目标文件大小;要目标大小得加follow_symlinks=True(默认就是 True) - 排序时用
sorted(..., key=lambda p: p.stat().st_size, reverse=True),reverse=True才是“从大到小”
PermissionError 和 FileNotFoundError 怎么安静跳过
遍历到系统目录(如 /proc、C:WindowsSystem32)时,os.scandir 或 pathlib.Path.iterdir() 会抛 PermissionError;删了一半的文件可能触发 FileNotFoundError。不处理就会中断整个流程。
- 在生成文件路径的循环里套
try/except,只捕获这两个异常,其他异常照常抛出(比如MemoryError就不该吞) - 别在
sorted的key函数里做stat()—— 这样异常发生时你连是哪个文件出的问题都不知道 - 示例片段:
try: size = p.stat().st_size except (OSError, IOError): continue(OSError是PermissionError和FileNotFoundError的父类)
输出结果时,路径长度和编码别让终端炸掉
Linux/macOS 终端一般没问题,但 Windows CMD 默认用 gbk 编码,遇到中文路径直接 UnicodeEncodeError;另外超长路径(>260 字符)在 Windows 上可能被截断或报错。
- 打印前用
str(p.resolve())而不是str(p),确保是绝对路径、无..,也方便排查 - Windows 用户如果跑崩了,临时加一句
sys.stdout.reconfigure(encoding='utf-8')(Python 3.7+) - 真要处理超长路径,得在脚本开头加
import ctypes; ctypes.windll.kernel32.SetConsoleOutputCP(65001),但这只是治标;更稳的方式是用\?前缀调系统 API(太重,一般脚本没必要)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











