Python教程10:第一个实用程序

Python 教程 10:第一个实用程序 “纸上得来终觉浅,绝知此事要躬行。” 经过前面 9 课的学习,我们已经掌握了 Python 的基础知识。今天,让我们把这些知识串起来,开发一个真正实用的程序:批量文件重命名工具。 1. 项目需求 开发一个命令行工具,能够: 批量重命名文件:支持添加前缀、后缀、替换文本 过滤文件:支持按扩展名、文件名模式过滤 预览模式:先预览修改,确认后再执行 撤销功能:记录操作,支持撤销 这个工具很实用,能解决日常工作中的真实问题。 2. 项目结构 file_renamer/ ├── file_renamer.py # 主程序 ├── renamer.py # 核心重命名逻辑 ├── utils.py # 工具函数 └── history.json # 操作历史记录 3. 核心功能实现 3.1 列出目录中的文件 1# utils.py 2import os 3 4def list_files(directory, extension=None, pattern=None): 5 """ 6 列出目录中的文件 7 8 Args: 9 directory: 目标目录 10 extension: 文件扩展名过滤(如'.txt') 11 pattern: 文件名模式(简单的包含匹配) 12 13 Returns: 14 文件路径列表 15 """ 16 files = [] 17 18 for filename in os.listdir(directory): 19 filepath = os.path.join(directory, filename) 20 21 # 只处理文件,忽略目录 22 if not os.path.isfile(filepath): 23 continue 24 25 # 扩展名过滤 26 if extension and not filename.endswith(extension): 27 continue 28 29 # 文件名模式过滤 30 if pattern and pattern not in filename: 31 continue 32 33 files.append(filepath) 34 35 return files 3.2 重命名逻辑 1# renamer.py 2import os 3import re 4 5class FileRenamer: 6 """文件重命名器""" 7 8 def __init__(self, directory): 9 self.directory = directory 10 self.changes = [] # 记录修改 11 12 def add_prefix(self, files, prefix): 13 """添加前缀""" 14 for filepath in files: 15 dirname = os.path.dirname(filepath) 16 filename = os.path.basename(filepath) 17 new_name = prefix + filename 18 new_path = os.path.join(dirname, new_name) 19 self.changes.append((filepath, new_path)) 20 21 def add_suffix(self, files, suffix): 22 """添加后缀(在扩展名前)""" 23 for filepath in files: 24 dirname = os.path.dirname(filepath) 25 filename = os.path.basename(filepath) 26 name, ext = os.path.splitext(filename) 27 new_name = name + suffix + ext 28 new_path = os.path.join(dirname, new_name) 29 self.changes.append((filepath, new_path)) 30 31 def replace_text(self, files, old_text, new_text): 32 """替换文件名中的文本""" 33 for filepath in files: 34 dirname = os.path.dirname(filepath) 35 filename = os.path.basename(filepath) 36 new_name = filename.replace(old_text, new_text) 37 new_path = os.path.join(dirname, new_name) 38 if filepath != new_path: # 只记录有变化的 39 self.changes.append((filepath, new_path)) 40 41 def preview(self): 42 """预览修改""" 43 if not self.changes: 44 print("没有要修改的文件") 45 return 46 47 print(f"\n将要进行 {len(self.changes)} 项修改:") 48 print("-" * 60) 49 for i, (old, new) in enumerate(self.changes, 1): 50 old_name = os.path.basename(old) 51 new_name = os.path.basename(new) 52 print(f"{i}. {old_name} -> {new_name}") 53 print("-" * 60) 54 55 def execute(self): 56 """执行重命名""" 57 if not self.changes: 58 print("没有要执行的操作") 59 return 60 61 success_count = 0 62 for old_path, new_path in self.changes: 63 try: 64 os.rename(old_path, new_path) 65 success_count += 1 66 except Exception as e: 67 print(f"错误:{old_path} -> {e}") 68 69 print(f"\n成功重命名 {success_count}/{len(self.changes)} 个文件") 70 71 # 保存操作历史 72 self.save_history() 73 74 def save_history(self): 75 """保存操作历史(简化版)""" 76 import json 77 from datetime import datetime 78 79 history_file = "history.json" 80 81 # 读取现有历史 82 history = [] 83 if os.path.exists(history_file): 84 with open(history_file, 'r', encoding='utf-8') as f: 85 history = json.load(f) 86 87 # 添加新记录 88 history.append({ 89 'time': datetime.now().isoformat(), 90 'changes': [(old, new) for old, new in self.changes] 91 }) 92 93 # 保存 94 with open(history_file, 'w', encoding='utf-8') as f: 95 json.dump(history, f, indent=2, ensure_ascii=False) 3.3 主程序 1# file_renamer.py 2#!/usr/bin/env python3 3# -*- coding: utf-8 -*- 4 5""" 6文件批量重命名工具 7 8用法: 9 python file_renamer.py 10""" 11 12import os 13from renamer import FileRenamer 14from utils import list_files 15 16def main(): 17 print("=" * 60) 18 print("文件批量重命名工具") 19 print("=" * 60) 20 21 # 获取目录 22 directory = input("\n请输入目录路径(留空使用当前目录):").strip() 23 if not directory: 24 directory = "." 25 26 if not os.path.exists(directory): 27 print(f"错误:目录 '{directory}' 不存在") 28 return 29 30 # 获取文件过滤条件 31 extension = input("文件扩展名过滤(如.txt,留空跳过):").strip() 32 if not extension: 33 extension = None 34 35 # 列出文件 36 files = list_files(directory, extension) 37 38 if not files: 39 print("没有找到符合条件的文件") 40 return 41 42 print(f"\n找到 {len(files)} 个文件") 43 44 # 创建重命名器 45 renamer = FileRenamer(directory) 46 47 # 操作菜单 48 while True: 49 print("\n请选择操作:") 50 print("1. 添加前缀") 51 print("2. 添加后缀") 52 print("3. 替换文本") 53 print("4. 预览修改") 54 print("5. 执行重命名") 55 print("0. 退出") 56 57 choice = input("\n请输入选择:").strip() 58 59 if choice == "1": 60 prefix = input("请输入前缀:") 61 renamer.add_prefix(files, prefix) 62 print("✓ 已添加前缀规则") 63 64 elif choice == "2": 65 suffix = input("请输入后缀:") 66 renamer.add_suffix(files, suffix) 67 print("✓ 已添加后缀规则") 68 69 elif choice == "3": 70 old_text = input("请输入要替换的文本:") 71 new_text = input("请输入新文本:") 72 renamer.replace_text(files, old_text, new_text) 73 print("✓ 已添加替换规则") 74 75 elif choice == "4": 76 renamer.preview() 77 78 elif choice == "5": 79 renamer.preview() 80 confirm = input("\n确认执行?(y/N):").strip().lower() 81 if confirm == 'y': 82 renamer.execute() 83 break 84 else: 85 print("已取消") 86 87 elif choice == "0": 88 print("再见!") 89 break 90 91 else: 92 print("无效的选择") 93 94if __name__ == "__main__": 95 main() 4. 使用示例 场景 1:照片重命名 假设有一批照片: ...

2024-03-18 · 4 min · 787 words · Hank