shutil.disk_usage()返回字节值,需手动转换为gb/gib;路径必须存在且为目录,windows需用"c:"格式,linux用"/",不可用于文件路径。

shutil.disk_usage() 返回的是字节,不是 GB 或 MB
直接打印 shutil.disk_usage(path) 的结果会看到三个大整数,比如 (123456789012, 34567890123, 88888888889),分别对应 total、used、free —— 全是字节。人眼很难判断这是 115GB 还是 82TB。
- 别用
print(shutil.disk_usage('.'))就完事,得自己转换单位 - 推荐除以
1024**3转 GB(二进制 GiB),或1000**3转 GB(十进制,和厂商标称一致) - Windows 资源管理器显示的是 GiB(1024 进制),但磁盘厂标的是 GB(1000 进制),差约 7% —— 别怀疑函数算错了
示例:
import shutil
total, used, free = shutil.disk_usage('.')
print(f"空闲: {free / 1024**3:.2f} GiB")
传入路径必须存在且可访问,否则抛 OSError
shutil.disk_usage() 不会自动向上找挂载点,也不处理符号链接跳转。如果给一个不存在的目录、没权限的路径、或已断开的网络驱动器,直接报 OSError: [WinError 21] 设备未就绪 或 Permission denied。
- 务必先用
os.path.exists()和os.access(path, os.R_OK)做前置检查 - 想查 C 盘?别传
"C:",要传"C:\"(Windows)或"/"(Linux/macOS)—— 缺少结尾分隔符可能被当成相对路径 - 在容器或 CI 环境中,
/tmp可能是内存文件系统(tmpfs),disk_usage返回的 free 并不反映物理磁盘余量
跨平台行为一致,但 Windows 下要注意盘符格式
函数本身在 Linux/macOS/Windows 上行为统一,但 Windows 对路径字符串更敏感:传 "c:"、"c"、"C" 都会失败;必须是 "C:" 或 "C:/"(注意冒号和斜杠)。
- 安全写法:
os.path.abspath(os.path.join(drive_letter + ':', os.sep)),比如生成"C:\\" - 用
pathlib.Path("C:/").resolve()更可靠,它会自动规范化为C: - Linux 下
"/mnt/data"如果是独立挂载分区,返回的是该分区数据;如果是 bind mount 或 overlayfs,可能返回宿主文件系统的值
不支持获取单个文件所在分区的剩余空间
有人想“查一下这个日志文件写进去会不会爆盘”,于是传入 shutil.disk_usage("/var/log/app.log") —— 这会报错,因为函数只接受目录路径,且要求是挂载点根目录或其子目录(但不能是普通文件)。
立即学习“Python免费学习笔记(深入)”;
- 正确做法:先用
os.path.dirname(file_path)拿到父目录,再不断os.path.dirname()向上直到os.stat()的st_dev不变,或用shutil.disk_usage()成功为止 - 更简单:直接对
os.path.dirname(file_path)调用,大多数情况下足够(除非父目录本身是挂载点) - 极端情况(如 Btrfs 子卷、ZFS 数据集),
disk_usage返回的是整个池的值,无法反映该子卷配额限制
exists 检查,半夜报警全是 OSError,而不是磁盘快满。










