用Python按文件后缀名自动归类桌面文件 防覆盖与预览
在日常开发中,桌面或下载目录常常堆满各种后缀的文件:PDF、图片、压缩包、代码文件混在一起,找文件时非常低效。利用 Python 内置的 os、shutil 和 pathlib 模块,可以写一个按后缀名自动归档的小脚本,不仅不依赖第三方库,还能避免同名覆盖,并提供 dry_run 预览模式,适合作为 Python 文件处理入门的练手项目。一、设计思路
核心逻辑很简单:遍历目标目录下的文件,提取每个文件的后缀名,根据预设的映射表把文件移动到对应分类文件夹中。如果分类文件夹不存在则自动创建;如果目标位置已有同名文件,则自动追加序号防止覆盖。为了安全,先通过 dry_run 模式只打印移动计划,确认无误后再真正执行移动。
二、环境与使用前提
脚本使用 Python 3 运行,只需标准库,无需 pip 安装额外包。适用于 Windows、macOS、Linux 桌面环境。运行时需要确保对目标目录有读写权限,文件被占用时可能跳过并记录错误。
三、完整代码实现
import os
import shutil
from pathlib import Path
# 文件类型分类规则
FILE_CATEGORIES = {
# 文档类
'.pdf': 'PDF文档',
'.doc': 'Word文档',
'.docx': 'Word文档',
'.wps': 'Word文档',
# 表格类
'.xls': 'Excel表格',
'.xlsx': 'Excel表格',
'.csv': 'Excel表格',
'.tsv': 'Excel表格',
# 演示类
'.ppt': 'PPT演示',
'.pptx': 'PPT演示',
# 图片类
'.jpg': '图片',
'.jpeg': '图片',
'.png': '图片',
'.gif': '图片',
'.bmp': '图片',
'.svg': '图片',
'.webp': '图片',
'.ico': '图片',
'.tiff': '图片',
# 视频类
'.mp4': '视频',
'.avi': '视频',
'.mov': '视频',
'.mkv': '视频',
'.flv': '视频',
'.wmv': '视频',
# 音频类
'.mp3': '音频',
'.wav': '音频',
'.flac': '音频',
'.aac': '音频',
'.ogg': '音频',
# 压缩包类
'.zip': '压缩包',
'.rar': '压缩包',
'.7z': '压缩包',
'.tar': '压缩包',
'.gz': '压缩包',
# 代码类
'.py': '代码文件',
'.js': '代码文件',
'.java': '代码文件',
'.c': '代码文件',
'.cpp': '代码文件',
'.html': '代码文件',
'.css': '代码文件',
# 其他
'.txt': '文本文件',
'.md': '文本文件',
'.exe': '可执行程序',
'.msi': '可执行程序',
'.dmg': '可执行程序',
}
def organize_files(target_dir, dry_run=False):
"""
按文件后缀名自动归类文件夹中的文件
参数:
target_dir: 要整理的目录路径
dry_run: True=只预览不移动,False=执行移动
"""
target_path = Path(target_dir)
if not target_path.exists():
print(f"错误:目录 {target_dir} 不存在!")
return
moved_count = 0
skipped_count = 0
errors = []
# 遍历目录中的所有文件(不递归子文件夹)
for file_path in target_path.iterdir():
if file_path.is_dir():
continue
# 获取文件后缀并统一小写,避免 .PDF 和 .pdf 被分开
suffix = file_path.suffix.lower()
category = FILE_CATEGORIES.get(suffix, '其他文件')
# 创建分类文件夹
category_dir = target_path / category
category_dir.mkdir(exist_ok=True)
# 构造目标路径
dest = category_dir / file_path.name
# 如果目标已存在,加序号避免覆盖
if dest.exists():
stem = file_path.stem
counter = 1
while dest.exists():
dest = category_dir / f"{stem}_{counter}{suffix}"
counter += 1
# 执行移动或预览
if dry_run:
print(f"[预览] {file_path.name} → {category}/")
moved_count += 1
else:
try:
shutil.move(str(file_path), str(dest))
print(f"[已移动] {file_path.name} → {category}/")
moved_count += 1
except Exception as e:
errors.append(f"{file_path.name}: {e}")
skipped_count += 1
# 汇总报告
print(f"\n{'='*40}")
print(f"整理完成!")
print(f"移动文件: {moved_count} 个")
if skipped_count > 0:
print(f"跳过文件: {skipped_count} 个")
if errors:
print(f"\n错误列表:")
for err in errors:
print(f" - {err}")
if __name__ == "__main__":
# 先预览:organize_files(r"C:\Users\用户名\Desktop", dry_run=True)
# 再执行:organize_files(r"C:\Users\用户名\Desktop", dry_run=False)
organize_files(r"D:\Downloads", dry_run=False)
四、关键实现细节
1. 用 pathlib 替代 os.path 简化路径处理
Path(target_dir) 生成路径对象后,可以直接用 / 拼接路径,用 .suffix 获取扩展名,用 .name 取文件名,比 os.path 更简洁。例如 f.suffix 等价于 os.path.splitext(f),f.name 等价于 os.path.basename(f)。
2. 后缀统一转小写
file_path.suffix.lower() 能避免 .PDF 和 .pdf 因大小写不同而被分到不同文件夹。这是实际操作中很常见的问题,Windows 大小写不敏感,但 macOS 和 Linux 大小写敏感。
3. 防覆盖处理
当同名文件已经存在于目标分类目录时,脚本会基于原文件名的主干部分追加序号:比如“报告.pdf”变成“报告_1.pdf”,如果还有冲突再继续尝试“报告_2.pdf”。这个逻辑通过 while dest.exists() 循环实现,避免了 shutil.move 直接覆盖同名文件导致的数据丢失。
4. dry_run 安全预览
dry_run=True 时只打印每个文件的移动去向,不执行任何移动操作。建议首次运行先打开预览,确认分类规则符合预期再真正执行。
五、扩展技巧
技巧1:按文件大小二次归类
可以在移动前读取 file_path.stat().st_size,按照字节数划分“小文件(<1MB)”“中等文件(1-100MB)”“大文件(>100MB)”,然后拼接到分类文件夹名中,实现二级分类。
技巧2:按创建月份归档
使用 datetime.fromtimestamp(file_path.stat().st_ctime) 获取文件创建时间,再用 strftime('%Y-%m') 生成如“2025-03”的月份文件夹,适合按时间维度整理日志或截图。
技巧3:清理整理后的空文件夹
在移动完成后,可以用 os.walk 从下往上遍历,删除所有既没有文件也没有子目录的空目录,保持目录结构干净。
六、常见问题与处理
Q1:移动后找不到文件?
文件名没有改变,只是被移动到了目标目录下的分类子文件夹中。在移动前先运行 dry_run=True 可以避免误操作。
Q2:提示“文件正在使用中”?
原文件可能被其他程序打开或占用。关闭相关程序后重新运行;或者从脚本输出的错误列表中找到对应文件,手动处理。
Q3:想忽略 .lnk、.ini 这类后缀?
在遍历循环开头增加判断即可:
if file_path.suffix.lower() in ('.lnk', '.ini', '.tmp'):
continue
七、总结
这个脚本的核心操作可以概括为四步:获取小写后缀、查映射表得到分类名、创建分类目录、用 shutil.move 移动文件。加上防覆盖序号和 dry_run 预览后,已经能安全应对绝大多数桌面整理场景。你还可以根据个人习惯自由增删 FILE_CATEGORIES 中的映射关系,比如把 .log 归入文本文件,把 .psd 归入图片,让整理规则更符合自己的工作流。
Re: 用Python按文件后缀名自动归类桌面文件 防覆盖与预览
思路很清晰,代码也简洁易懂。`dry_run` 预览和防覆盖这两个设计很实用,适合拿来当 Python 文件处理的练习项目。分类映射表也列得挺全,基本覆盖了日常常见类型,后续自己加规则也方便。 有一点小建议:目前只处理目标目录下的文件,如果子文件夹也需要整理,可以考虑加个递归遍历;另外如果遇到只读文件或权限不足,记录错误后跳过也够稳了。整体很实用,收藏了。Re: 用Python按文件后缀名自动归类桌面文件 防覆盖与预览
这个脚本思路很清晰,适合入门练习。分类映射做得很全,后缀统一小写也考虑到了大小写变体,避免重复分类。dry_run 预览模式很实用,整理前先看效果,能减少误操作。有个小建议:如果以后想处理子目录里的文件,可以加个 `rglob('*')` 的选项;另外遇到无法移动的文件(比如被占用)时,目前只是记录错误,可以考虑把未移动的清单汇总输出,方便手动处理。整体代码简洁,注释也挺到位,学习了。Re: 用Python按文件后缀名自动归类桌面文件 防覆盖与预览
这个脚本思路很清晰,分类映射表也照顾到了常见文件类型,作为入门练手确实很合适。尤其是 dry_run 预览和重名自动加序号这两个细节,能避免不少误操作,对新手很友好。 提个小小的使用感受:预览模式下如果也会创建分类文件夹,可能会让用户觉得“还没执行怎么目录就出来了”,不过影响不大。另外“其他文件”目前是直接放进目标目录下的“其他文件”文件夹,也可以考虑要不要保留原位置不动,看个人习惯。整体来说代码简洁,标准库实现,直接就能跑,适合拿来改造成自己的整理工具。
页:
[1]