恭喜你进入 第二阶段:实战脚本篇。
在这个阶段,我们将跨越“语法”和“应用”的鸿沟。作为开发者,你知道写代码最爽的时刻就是让电脑帮你做那些重复、枯燥的工作。
项目目标:编写一个 Python 脚本,一键清理你乱七八糟的“下载”文件夹(Downloads),根据文件后缀名自动归类到 Images, Docs, Installers 等文件夹中。
核心知识点:
pathlib库:Python 3.4+ 引入的现代路径操作库(比老旧的os.path更优雅,面向对象风格)。shutil库:用于高级文件操作(移动、复制、删除)。字典映射:利用字典优化大量的
if-elif判断。异常处理:防止因为一个文件移动失败(如被占用)导致整个脚本崩溃。
前置准备:理解路径操作
在 Node.js 中你可能习惯用 path.join(__dirname, 'file.txt')。
在现代 Python 中,我们使用 pathlib.Path 对象,它重载了 / 运算符,让路径拼接非常直观。
Python
from pathlib import Path
# 获取当前脚本所在目录
current_dir = Path.cwd()
# 路径拼接 (是不是比 os.path.join 优雅?)
target_file = current_dir / "downloads" / "test.jpg"
print(target_file.name) # test.jpg
print(target_file.suffix) # .jpg
print(target_file.stem) # test
print(target_file.exists()) # True/False实战代码:文件整理神器 (File Organizer)
建议在桌面上新建一个测试文件夹(比如 test_folder),里面随便放几个 txt, jpg, pdf 文件来运行此脚本,不要直接在你的重要目录运行,防止误操作。
新建文件 organizer.py:
Python
import shutil
from pathlib import Path
# 1. 配置:定义文件后缀与目标文件夹的映射关系
# 这种配置方式比写一堆 if suffix == '.jpg' 更易维护
FILE_FORMATS = {
"Images": [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp"],
"Documents": [".pdf", ".docx", ".doc", ".txt", ".xlsx", ".pptx", ".md"],
"Archives": [".zip", ".rar", ".7z", ".tar", ".gz"],
"Code": [".py", ".js", ".html", ".css", ".java", ".json"],
"Installers":[".exe", ".msi", ".dmg", ".pkg", ".deb"]
}
def organize_directory(path_str):
"""
核心整理函数
:param path_str: 要整理的文件夹路径 (字符串)
"""
# 将字符串转换为 Path 对象
base_dir = Path(path_str)
# 检查路径是否存在
if not base_dir.exists():
print(f"❌ 错误:路径不存在 -> {base_dir}")
return
print(f"📂 正在整理:{base_dir} ...")
# 2. 遍历目录下的所有内容 (iterdir 类似 ls 命令)
for item in base_dir.iterdir():
# 我们只处理文件,忽略文件夹,避免递归混乱
if item.is_dir():
continue
# 忽略脚本自身 (防止把自己也移走了)
if item.name == Path(__file__).name:
continue
# 获取文件后缀 (转小写,防止 .JPG 和 .jpg 识别为不同)
file_suffix = item.suffix.lower()
# 3. 核心逻辑:查找该文件属于哪个分类
destination_folder = "Others" # 默认分类
# 遍历配置字典
# folder_name 是键 (如 "Images"), extensions 是值 (列表)
for folder_name, extensions in FILE_FORMATS.items():
if file_suffix in extensions:
destination_folder = folder_name
break # 找到了就停止循环
# 4. 移动操作
target_dir = base_dir / destination_folder
# 这一步很关键:如果目标文件夹不存在,自动创建
# exist_ok=True 表示如果文件夹已存在,不报错
target_dir.mkdir(exist_ok=True)
# 构建目标文件的完整路径
target_path = target_dir / item.name
try:
# 移动文件 (shutil.move)
shutil.move(str(item), str(target_path))
print(f"✅ 移动: {item.name} -> {destination_folder}/")
except Exception as e:
# 5. 异常处理:如果是“文件已存在”或“被占用”,打印错误但不崩溃
print(f"⚠️ 跳过: {item.name} (原因: {e})")
if __name__ == "__main__":
# 输入你要整理的路径,"." 代表当前目录
target_path = input("请输入要整理的文件夹路径 (默认为当前目录): ").strip() or "."
organize_directory(target_path)
print("\n🎉 整理完成!")深度解析 (Document)
1. 为什么用 pathlib 而不是 os?
传统方式 (
os):os.path.join(dir, file)返回的是字符串。你需要手动切分字符串来获取后缀名。现代方式 (
pathlib):Path(dir) / file返回的是对象。你可以直接调用.suffix(后缀),.stem(文件名),.parent(父目录)。这更符合 OOP (面向对象) 思维,代码可读性极高。
2. 字典结构的设计逻辑
作为开发者,我们要避免“硬编码 (Hard Coding)”。
初级写法:
Python
Pythonif suffix == '.jpg' or suffix == '.png': folder = 'Images' elif suffix == '.pdf': folder = 'Docs'这种写法如果要增加格式,你需要改动逻辑代码。
高级写法 (配置分离):
使用字典
FILE_FORMATS。如果未来你想支持.mp4,只需要在字典里的Videos列表加一项即可,逻辑代码(Loop部分)完全不需要动。
3. try...except 的重要性
在文件操作中,不可控因素非常多:
文件正在被 Word 打开(无法移动)。
目标文件夹里已经有一个同名文件(Windows 下会报错,Linux 下可能会覆盖)。
权限不足。
如果不加
try...except,处理第 3 个文件报错时程序就会挂掉,剩下的 97 个文件就不会被处理。
课后挑战 (Homework)
为了让你“由浅入深”,请尝试在上述代码基础上增加以下功能(遇到困难可以把需求发给我,我给你提示):
处理重名文件:目前的
shutil.move如果遇到同名文件可能会报错。请修改逻辑:如果目标文件夹已有file.txt,则自动重命名为file_1.txt再移动。按日期归类:不再按后缀名,而是按文件的“修改日期”归类。例如创建
2023-10,2023-11文件夹。提示:使用item.stat().st_mtime获取时间戳。
搞定这个脚本,你就掌握了 Python 处理系统任务的核心能力。下一步我们将进入 Web 交互与爬虫 领域,去获取互联网上的数据。准备好了吗?