ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

【Python项目实战】项目·下载文件夹整理助手:pathlib按类型自动归类

【Python项目实战】项目·下载文件夹整理助手:pathlib按类型自动归类 下载文件夹里300个文件躺成一片找一张上周的截图要翻两分钟今天写一个“自动收纳师”写完当天就能用上。本篇成品一条命令按类型整理任意文件夹——图片、文档、压缩包各归各位重名文件绝不覆盖。还带预览模式先看它打算干什么再决定让它干。含注释120行左右。 太长不看版给想快速上手的你项目信息一句话说明项目名称下载文件夹整理助手File Organizer代码行数~120行含注释依赖零依赖Python自带模块核心功能按扩展名自动归类 重名保护 预览模式跑起来的命令python main.py ~/Downloads --dry-run先预览再执行技术点pathlib、shutil.move、argparse开关参数做完你能得到第一个能真正改变你电脑文件的工具一、成品预览$ python main.py ~/Downloads --dry-run [预览] 报告.pdf → 文档/ [预览] IMG_2026.jpg → 图片/ [预览] setup.exe → 安装包/ [预览] 神曲.mp3 → 音频/ [预览] 未命名.psd → 其他/ —— 预览 5 个文件未做任何改动 —— 预览模式未做任何改动去掉 --dry-run 正式执行 $ python main.py ~/Downloads 已移动报告.pdf → 文档/ 已移动IMG_2026.jpg → 图片/ 已移动setup.exe → 安装包/ 已移动神曲.mp3 → 音频/ 已移动未命名.psd → 其他/ —— 整理 5 个文件 —— $ ls ~/Downloads # Windows用dir 文档 图片 安装包 音频 其他 和上一篇的待办清单比这个项目特殊在哪⚠️它会动你磁盘上的真实文件。所以本篇除了代码还有三个安全设计安全设计作用️预览模式dry-run先看它打算干什么确认无误再执行️重名不覆盖两个报告.pdf→ 第二个自动变报告(1).pdf️只动文件不递归只整理当前层不动子文件夹里的文件这三个习惯会让你以后写的每一个“会改东西”的脚本都值得信任。二、前置知识pathlib四件套 一个搬运工上一项目见过Path这次用它的四个核心技能技能写法说明遍历文件夹folder.iterdir()逐个给出里面的文件和文件夹判断item.is_dir()/dest.exists()是文件夹吗 / 路径存在吗拆文件名item.suffix/item.stem报告.pdf→ 后缀.pdf、名字报告换个名字dest.with_name(新名.pdf)同文件夹下改个名字再配一个搬运工shutil.move(源, 目标)—— 把文件从一个路径移到另一个路径。⚠️注意item.suffix返回的后缀自带一个点.pdf而不是pdf。记住这个细节第九节③有个著名的坑等着它。三、第0步setup3分钟流程已是老朋友1. 新建文件夹organizerVSCode打开 2. python -m venv venv 3. 激活windows: venv\Scripts\activatecmd | .\venv\Scripts\Activate.ps1PowerShell mac: source venv/bin/activate 4. git init写好.gitignore 5. 新建空文件main.py 零依赖项目venv照建——习惯不因项目而变。四、第1步规则表——把分类逻辑写成一份数据先别急着写功能代码。分类的本质是什么查表拿到扩展名查它属于哪一类。那就把表写出来organizer —— 下载文件夹整理助手importargparseimportshutilfrompathlibimportPath# 扩展名 → 文件夹 的归类规则想加类别在这里加一行就行RULES{图片:[.jpg,.jpeg,.png,.gif,.webp,.bmp],文档:[.pdf,.docx,.doc,.txt,.md,.xlsx,.pptx],压缩包:[.zip,.rar,.7z,.tar,.gz],安装包:[.exe,.msi,.dmg,.pkg],视频:[.mp4,.mkv,.mov,.avi],音频:[.mp3,.wav,.flac,.m4a],}defclassify(suffix:str)-str:查规则表这个扩展名该进哪个文件夹都不认识就进其他 forfolder,extsinRULES.items():ifsuffix.lower()inexts:# .lower() 让 .JPG 和 .jpg 一视同仁returnfolderreturn其他 体会一下这个设计好在哪里说明数据驱动分类规则全在RULES里classify只是查表的人易扩展以后想加“电子书”类别改数据就行一行逻辑代码都不用动容错suffix.lower()让.JPG和.jpg一视同仁把变化放进数据把逻辑写成通用——这是好程序的第一个形状。五、第2步重名保护——数据无价重点如果不做任何保护两个都叫报告.pdf的文件后到的会悄悄覆盖先到的——没有任何提示丢了就是丢了。defunique_path(dest:Path)-Path:目标已存在就起个不重名的新名字报告.pdf → 报告(1).pdfifnotdest.exists():returndest stem,extdest.stem,dest.suffix n1whileTrue:candidatedest.with_name(f{stem}({n}){ext})ifnotcandidate.exists():returncandidate n1逻辑简单粗暴报告.pdf 被占了 → 试试 报告(1).pdf 报告(1).pdf 也被占了 → 试试 报告(2).pdf 直到没人用为止 ✅ 以后你写任何涉及移动、复制、写文件的代码都先想想这句口诀写文件操作前先问“会不会覆盖”。六、第3步主流程——遍历、跳过、预览或搬移deforganize(folder:Path,dry_run:boolFalse):主流程遍历 → 分类 → 预览或搬移moved0foriteminsorted(folder.iterdir()):# 跳过文件夹和隐藏文件.DS_Store这类ifitem.is_dir()oritem.name.startswith(.):continuetarget_dirfolder/classify(item.suffix)destunique_path(target_dir/item.name)ifdry_run:print(f[预览]{item.name}→{target_dir.name}/)else:target_dir.mkdir(exist_okTrue)# 文件夹不存在就建shutil.move(str(item),str(dest))print(f已移动{item.name}→{target_dir.name}/)moved1action预览ifdry_runelse整理print(f——{action}{moved}个文件 ——)ifdry_run:print(预览模式未做任何改动去掉 --dry-run 正式执行) 三个安全细节都在这一段里安全点代码作用不搬文件夹if item.is_dir(): continue包括我们自己生成的归类文件夹不会搬自己家不搬隐藏文件if item.name.startswith(.)跳过Mac的.DS_Store等系统文件预览/执行分离if dry_run:同一个逻辑只差“搬”这一个动作预览模式的精髓计划与执行分离。先看计划再决定是否执行。七、第4步argparse接上两个开关defmain():parserargparse.ArgumentParser(description下载文件夹整理助手)parser.add_argument(folder,nargs?,default.,help要整理的文件夹路径默认当前目录)parser.add_argument(--dry-run,actionstore_true,help预览模式只显示计划不动任何文件)argsparser.parse_args()folderPath(args.folder).expanduser()# ~ 自动展开成用户主目录ifnotfolder.is_dir():print(f文件夹不存在{folder})returnorganize(folder,dry_runargs.dry_run)if__name____main__:main() 两个新知识点知识点写法效果可选参数nargs?default.不传路径就整理当前目录开关参数actionstore_true写了--dry-run它就是True不写就是False路径展开.expanduser()把~翻译成你的主目录/Users/你或C:\Users\你八、第5步验收——先沙盒后实战重点文件操作脚本有一条铁律先在沙盒里验证再上真实数据。千万别拿下载文件夹当小白鼠。第一步造一个沙盒并塞满假文件VSCode终端执行# 建沙盒mkdirsandboxcdsandbox# 造假文件Windows用 echo hi 文件名echohi报告.pdfechohi神曲.mp3echohisetup.exeechohiIMG_001.jpgechohi未知.xyz# 回到项目根目录cd..第二步沙盒里先预览再实跑python main.py sandbox --dry-run# 看计划5个文件各归各类python main.py sandbox# 正式执行lssandbox# 图片/ 音频/ 安装包/ 文档/ 其他/全齐第三步真实战场先预览python main.py ~/Downloads --dry-run盯着清单看10秒——有没有不该动的文件确认无误去掉--dry-run正式执行。 从此你的下载文件夹一条命令治好。九、常见报错这6个全是“动文件”脚本的高发区重点① 路径带空格被切断C:\Users\my name\Downloads只认出了C:\Users\my 原因空格是参数分隔符。✅ 解法整个路径套引号python main.pyC:\Users\my name\Downloads②PermissionError: [Errno 13]移动到一半中断 原因文件正被别的程序占用——PDF还开着、视频还在播放器里、下载还没完成。✅ 解法关掉占用它的程序再跑本脚本可以放心重跑已搬好的会跳过在文件夹里是目录没搬的继续搬。③ 所有文件都进了其他 原因规则表里写的是pdf不是.pdf——suffix自带点.pdf查表永远查不中。✅ 解法用断点法盯一眼item.suffix的真实长相和你规则表里的键对一对。数据对不上先看数据的真实形状。④ 手机拍的.JPG全进了“其他” 原因classify里忘了suffix.lower()大写后缀查不到表。✅ 解法代码里已经防了如果你自查造一个.JPG假文件跑沙盒试试——这就是沙盒的第二个用处给边界情况做回归测试。⑤ “其他”文件夹里混着.DS_StoreMac 原因macOS会往文件夹里塞隐藏配置文件它们也是“文件”会被遍历到。✅ 解法startswith(.)已经跳过它们。Windows的隐藏文件desktop.ini也可以按这个逻辑处理。⑥ 自己写move没防重名老文件被悄悄覆盖 原因shutil.move(item, target_dir / item.name)遇到同名文件时行为会因操作系统而异——覆盖或报错都不受你控制。✅ 解法永远走unique_path。再念一遍口诀写文件操作前先问“会不会覆盖”。十、课后练习#练习难度提示1加类别给RULES加“电子书”.epub/.mobi/.azw3和“代码”.py/.ipynb/.html⭐改数据不改逻辑体会有多爽2安全升级把默认行为改成“只预览”加一个--yes参数才真正执行⭐⭐actionstore_true逻辑反过来3自动化测试雏形用循环造20个假文件跑整理断言各类别文件数正确⭐⭐⭐Path(f报告{i}.pdf).touch()4选做定时自动整理Windows用“任务计划程序”Mac用launchd每天21:00自动执行⭐⭐⭐⭐务必先跑过--dry-run确认无误再上定时 配套代码完整main.py与沙盒测试脚本已上传GitHub08-file-organizer/organizer【https://gitee.com/xqshadow/python-project-in-practice】
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进