移动文件前须用os.makedirs(path, exist_ok=true)创建目标目录,统一用os.path.join()拼接路径,扩展名转小写匹配并跳过隐藏文件,优先用shutil.move()并检查跨盘情况,桌面路径用pathlib.path.home()动态获取。

用 os 和 shutil 移动文件前必须检查目标目录是否存在
直接 shutil.move() 到一个不存在的目录会抛出 FileNotFoundError,不是权限问题也不是路径写错,就是父目录没建。桌面整理脚本最容易卡在这一步。
- 先用
os.makedirs(path, exist_ok=True)创建归档目录(比如"Documents"、"Images"),exist_ok=True能避免目录已存在时报错 - 别依赖用户手动建好这些文件夹——自动整理的前提就是“零预设”
- 路径拼接统一用
os.path.join(),别用字符串拼"Desktop/" + ext_dir,Windows 下反斜杠会出问题
扩展名匹配要小心大小写和隐藏文件
macOS 和 Linux 下常见 .DS_Store、.localized,Windows 有 Thumbs.db,这些不是真内容文件;另外 .JPG 和 .jpg 在 Linux 下是不同扩展名,但用户不关心这个区别。
- 用
os.path.splitext(filename)[1].lower()统一转小写再查表,否则.PNG会被漏掉 - 跳过以
.开头的文件(os.path.basename(path).startswith(".") == True),包括.gitignore这类配置文件,除非你明确想管它们 - 别只靠
filename.endswith(".pdf"),有些文件没扩展名或带多个点(如archive.tar.gz),优先按最后一点后的内容判断
shutil.move() 比 shutil.copy2() + os.remove() 更安全
有人想先复制再删原文件,觉得“保险”。其实只要源和目标在同一个磁盘分区,shutil.move() 底层调的是 os.rename(),是原子操作、快且不占额外空间;跨分区才退化为拷贝+删除——而这恰恰是你该拦截的场景。
- 用
shutil.disk_usage()对比源路径和目标路径的device(Linux/macOS)或驱动器号(Windows),提前提示“不能跨盘移动” - 如果真要跨盘,
shutil.move()仍可用,它自己会处理降级逻辑,不用你手动拆解 - 别在循环里对同一个文件反复
move:移动后原路径已无效,下次os.listdir()就看不到它了,无需额外过滤已处理项
桌面路径不能硬编码,要用 pathlib.Path.home() 动态获取
写死 "C:/Users/John/Desktop" 或 "/home/john/Desktop" 在别人机器上直接失效。更糟的是 macOS 用户桌面路径是 ~/Desktop,但 ~ 在某些 shell 环境下不展开。
立即学习“Python免费学习笔记(深入)”;
- 统一用
from pathlib import Path; desktop = Path.home() / "Desktop",Path对象天然跨平台 - 加一句
if not desktop.exists(): raise RuntimeError("Desktop directory not found"),比静默失败好 - 如果用户改过默认桌面路径(比如 OneDrive 同步桌面),
Path.home() / "Desktop"依然有效——系统级重定向由 OS 处理,Python 不用操心
"report_final_v2_REALLY_FINAL.pdf" 的文件,和旁边三个同名但大小差 2KB 的副本——自动整理不管重复,这事得人来判。










