问题场景
你是否遇到过这种情况:每天下载的文件散落在"下载"文件夹里,找一份上周的合同要翻半天?设计师的源文件、运营的活动素材、测试导出的数据全都混在一起,每次新建项目都要先花10分钟整理文件夹?
手动整理费时费力,今天清理完明天又乱了。如果你有类似困扰,那么Python可以帮你彻底解决这个问题——写一个脚本,让文件夹自动按规则整理,下载即归位。
核心方案
我们用Python的pathlib(更现代的文件操作库)和shutil(文件移动/复制)来实现自动化整理。主要功能包括:
按文件类型自动分类(图片、文档、视频、压缩包等)
按日期自动归档(今天/本周/本月)
定时监控整理(配合系统定时任务)
可配置的规则引擎(满足个性化需求)
代码实现
基础版:按文件类型分类
from pathlib import Path
import shutil
from collections import defaultdict
class FileOrganizer:
"""文件夹自动整理工具"""
# 定义文件类型映射规则
FILE_TYPES = {
'images': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.ico'],
'documents': ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt', '.md'],
'videos': ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv'],
'audio': ['.mp3', '.wav', '.flac', '.aac', '.ogg'],
'archives': ['.zip', '.rar', '.7z', '.tar', '.gz'],
'code': ['.py', '.js', '.html', '.css', '.java', '.cpp', '.go', '.rs', '.sh'],
'data': ['.csv', '.json', '.xml', '.yaml', '.yml', '.sql'],
}
def __init__(self, source_dir):
self.source_dir = Path(source_dir)
self.stats = defaultdict(int)
def get_category(self, file_path):
"""根据扩展名获取文件分类"""
suffix = file_path.suffix.lower()
for category, extensions in self.FILE_TYPES.items():
if suffix in extensions:
return category
return 'others'
def organize_by_type(self):
"""按文件类型整理"""
print(f"📂 开始整理文件夹: {self.source_dir}")
for file_path in self.source_dir.iterdir():
if not file_path.is_file():
continue
category = self.get_category(file_path)
target_dir = self.source_dir/category
# 创建分类目录
target_dir.mkdir(exist_ok=True)
# 移动文件
target_path = target_dir/file_path.name
if file_path != target_path: # 避免自身到自身的移动
shutil.move(str(file_path), str(target_path))
self.stats[category] += 1
print(f" ✅ {file_path.name} → {category}/")
self._print_stats()
def_print_stats(self):
"""打印整理统计"""
print("\n📊 整理完成:")
total = 0
for category, count in self.stats.items():
print(f" • {category}: {count} 个文件")
total += count
print(f" 总计移动: {total} 个文件")
使用方式:
# 整理下载文件夹
organizer = FileOrganizer("/Users/用户名/Downloads")
organizer.organize_by_type()
运行后,你会看到类似输出:
📂 开始整理文件夹: /Users/用户名/Downloads
✅ report.xlsx → documents/
✅ photo.jpg → images/
✅ data.csv → data/
✅ project.zip → archives/
📊 整理完成:
• documents: 5 个文件
• images: 12 个文件
• data: 3 个文件
• archives: 2 个文件
总计移动: 22 个文件
进阶版:按日期归档
很多文件需要按时间管理,比如日志、报表、财务凭证。按日期分类的版本:
from datetime import datetime
class DateFileOrganizer(FileOrganizer):
"""支持按日期归档的文件整理器"""
def get_date_folder(self, file_path):
"""根据文件修改时间计算目标文件夹"""
mtime = datetime.fromtimestamp(file_path.stat().st_mtime)
today = datetime.now()
# 计算天数差距
delta = (today-mtime).days
if delta == 0:
return"今天"
elif delta == 1:
return"昨天"
elif delta<7:
return"本周"
elif delta<30:
return"本月"
else:
return f"{mtime.strftime('%Y-%m')}"
def organize_by_date(self):
"""按文件修改日期整理"""
print(f"📅 按日期整理: {self.source_dir}")
for file_path in self.source_dir.rglob("*"):
if not file_path.is_file():
continue
# 跳过隐藏文件和系统文件夹
if file_path.name.startswith('.'):
continue
date_folder = self.get_date_folder(file_path)
target_dir = self.source_dir / date_folder
target_dir.mkdir(exist_ok=True)
target_path = target_dir / file_path.name
# 处理重名文件:添加序号
if target_path.exists() and target_path != file_path:
stem = target_path.stem
suffix = target_path.suffix
counter = 1
while target_path.exists():
target_path = target_dir / f"{stem}_{counter}{suffix}"
counter += 1
if file_path != target_path:
shutil.move(str(file_path), str(target_path))
self.stats[date_folder] += 1
self._print_stats()
完整版:定时监控整理
如果你希望下载完自动整理(而不是手动执行),可以用watchdog库监控文件夹变化:
# 安装:pip install watchdog
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
class DownloadHandler(FileSystemEventHandler):
"""监控下载文件夹的文件变化"""
def __init__(self, organizer):
self.organizer = organizer
# 只处理新创建的文件
self.pending_files = {}
def on_created(self, event):
"""文件创建时触发"""
if event.is_directory:
return
file_path = Path(event.src_path)
# 等待文件写入完成(文件大小稳定)
time.sleep(2)
# 检查文件是否还在变化
try:
size1 = file_path.stat().st_size
time.sleep(1)
size2 = file_path.stat().st_size
if size1 == size2: # 文件写入完成
print(f"\n📥 检测到新文件: {file_path.name}")
self._move_file(file_path)
except Exception as e:
print(f"处理文件出错: {e}")
def _move_file(self, file_path):
"""移动文件到对应分类"""
category = self.organizer.get_category(file_path)
target_dir = self.organizer.source_dir/category
# 创建分类目录
target_dir.mkdir(exist_ok=True)
target_path = target_dir/file_path.name
if target_path.exists():
stem = target_path.stem
suffix = target_path.suffix
target_path = target_dir / f"{stem}_{int(time.time())}{suffix}"
try:
shutil.move(str(file_path), str(target_path))
print(f" ✅ 已整理: {file_path.name} → {category}/")
except Exceptionase:
print(f" ❌ 移动失败: {e}")
def start_watching(source_dir):
"""启动文件夹监控"""
organizer = FileOrganizer(source_dir)
event_handler = DownloadHandler(organizer)
observer = Observer()
observer.schedule(event_handler, source_dir, recursive=False)
observer.start()
print(f"👀 开始监控文件夹: {source_dir}")
print("按 Ctrl+C 停止监控\n")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
print("\n👋 监控已停止")
observer.join()
# 启动监控
if __name__ == "__main__":
start_watching("/Users/用户名/Downloads")
定时任务配置
macOS/Linux:crontab
# 每天早上9点自动整理
09 * * * /usr/bin/python3 /path/to/organizer.py >> ~/logs/organize.log 2>&1
# 每小时整理一次
0 * * * * /usr/bin/python3 /path/to/organizer.py
Windows:任务计划程序
打开"任务计划程序"
创建基本任务 → 设置触发器(每天/每周)
操作选择"启动程序"
程序路径填写:pythonw.exe
参数填写:organizer.py
起始位置填写脚本所在目录
macOS: launchd
创建 ~/Library/LaunchAgents/com.organizer.plist:
<?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plistversion="1.0">
<dict>
<key>Label</key>
<string>com.organizer.folder</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/path/to/organizer.py</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
自定义规则
你可以根据实际需求扩展分类规则:
# 添加自定义分类
organizer.FILE_TYPES['design'] = ['.psd', '.ai', '.sketch', '.fig', '.xd']
organizer.FILE_TYPES['temp'] = ['.tmp', '.cache', '.bak']
# 或者按文件名关键词分类
CUSTOM_KEYWORDS = {
'contract': ['合同', '协议', 'contract', 'agreement'],
'invoice': ['发票', 'invoice', '账单'],
'report': ['报告', '报表', 'report', '数据'],
}
def organize_by_keyword(self, file_path):
"""按文件名关键词分类"""
name_lower = file_path.stem.lower()
for category, keywords in CUSTOM_KEYWORDS.items():
if any(kw.lower() in name_lower for kw in keywords):
return category
return None
完整脚本下载
整理好的完整可运行脚本已保存到项目目录,包含:
基础版(按类型分类)
日期版(按时间归档)
监控版(实时监控)
自定义配置示例
总结
| 场景 | 推荐方案 |
|---|
| 一次性整理历史文件 | 基础版 organize_by_type() |
| 需要按时间查找文件 | 日期版 organize_by_date() |
| 持续保持整洁 | 监控版 start_watching() |
| 每天定时整理 | 配合 crontab 使用基础版 |
核心就两个库:pathlib 处理路径,shutil 处理移动。学会这两个,你的文件管理能力就已经超过90%的用户了。
相关代码均为标准库或主流库,无需额外安装依赖(除监控功能需要 watchdog 外)