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

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

2024-03-18 · 3 min · 581 words · Hank

Python教程09:Python编码规范(PEP 8)

Python 教程 09:Python 编码规范(PEP 8) “代码的阅读次数远远多于编写次数。” PEP 8 是 Python 官方的编码规范,定义了如何写出"Pythonic"的代码。遵循这些规范,你的代码会更专业、更易读、更容易被其他 Python 程序员理解。 1. 什么是 PEP 8 PEP (Python Enhancement Proposal) 是 Python 增强提案。PEP 8 专门定义了 Python 代码的风格指南。 核心思想: 代码更多是被阅读,而不是被编写 一致性很重要 可读性至上 完整文档:https://peps.python.org/pep-0008/ 2. 缩进和空格 使用 4 个空格缩进 # 正确 def hello(): print("Hello") if True: print("World") # 错误:使用Tab或2个空格 def hello(): print("Hello") # 2个空格,不推荐 续行对齐 # 方法1:对齐左括号 result = some_function(argument1, argument2, argument3, argument4) # 方法2:悬挂缩进 result = some_function( argument1, argument2, argument3, argument4 ) # 列表、字典的续行 my_list = [ 1, 2, 3, 4, 5, 6, ] # 末尾逗号是好习惯 3. 空行 类和函数之间 # 顶层函数和类之间空2行 def function1(): pass def function2(): pass class MyClass: pass class AnotherClass: pass 方法之间 class MyClass: # 类中的方法之间空1行 def method1(self): pass def method2(self): pass 函数内部逻辑分组 def complex_function(): # 初始化部分 x = 10 y = 20 # 计算部分 result = x + y # 返回结果 return result 4. 最大行长度 每行不超过 79 个字符(文档字符串/注释不超过 72 个字符)。 ...

2024-03-02 · 3 min · 629 words · Hank

Python教程08:列表推导式入门

Python 教程 08:列表推导式入门 “简洁是智慧的灵魂。” —— 莎士比亚 列表推导式是 Python 最具特色的语法之一,它让你用一行代码完成原本需要多行循环才能实现的功能。这不仅是代码的简化,更是思维方式的提升。 1. 什么是列表推导式 列表推导式(List Comprehension)是一种简洁的创建列表的方式。 传统方法: # 生成1-10的平方 squares = [] for i in range(1, 11): squares.append(i ** 2) print(squares) # [1, 4, 9, 16, ..., 100] 列表推导式: # 一行搞定 squares = [i ** 2 for i in range(1, 11)] print(squares) # [1, 4, 9, 16, ..., 100] 代码从 3 行变成 1 行,清晰简洁,这就是 Python 的魅力。 2. 基本语法 [表达式 for 变量 in 序列] 执行过程: 遍历序列中的每个元素 将元素赋值给变量 计算表达式 将结果添加到新列表 # 示例 numbers = [1, 2, 3, 4, 5] # 每个数乘以2 doubled = [n * 2 for n in numbers] print(doubled) # [2, 4, 6, 8, 10] # 转换为字符串 str_list = [str(n) for n in numbers] print(str_list) # ['1', '2', '3', '4', '5'] # 调用方法 names = ['alice', 'bob', 'charlie'] capitalized = [name.capitalize() for name in names] print(capitalized) # ['Alice', 'Bob', 'Charlie'] 3. 带条件的列表推导式 可以添加 if 条件进行过滤: ...

2024-02-28 · 4 min · 790 words · Hank

Python教程07:字符串深入

Python 教程 07:字符串深入 “语言是思维的外壳。” 字符串是编程中最常用的数据类型之一,几乎每个程序都要处理文本。今天我们深入学习 Python 字符串的各种操作,从格式化到正则表达式,让你处理文本得心应手。 1. 字符串的创建 Python 中创建字符串有多种方式: # 单引号 s1 = 'Hello' # 双引号 s2 = "World" # 三引号(多行字符串) s3 = """这是一个 多行 字符串""" s4 = '''也可以用 单引号''' # 原始字符串(忽略转义字符) path = r"C:\Users\name\documents" # \n不会被解释为换行 # 字符串拼接 full = s1 + " " + s2 # "Hello World" 2. 字符串格式化:三种武器 方法 1:%格式化(老式,不推荐) name = "张三" age = 25 print("我叫%s,今年%d岁" % (name, age)) # 格式控制 pi = 3.14159 print("π = %.2f" % pi) # 保留2位小数 方法 2:format()方法 # 位置参数 print("{}+{}={}".format(1, 2, 3)) # 索引 print("{0}+{1}={2}".format(1, 2, 3)) print("{2}+{1}={0}".format(3, 2, 1)) # 调换顺序 # 关键字参数 print("{name}今年{age}岁".format(name="李四", age=30)) # 格式控制 print("{:.2f}".format(3.14159)) # 3.14 print("{:0>5}".format(42)) # 00042(左侧填充0,总宽度5) print("{:*^10}".format("Hi")) # ****Hi****(居中,宽度10,填充*) 方法 3:f-string(Python 3.6+,最推荐) name = "王五" age = 28 city = "北京" # 简洁直观 print(f"{name}今年{age}岁,来自{city}") # 表达式 print(f"明年我{age + 1}岁") print(f"2的10次方是{2 ** 10}") # 格式控制 pi = 3.14159 print(f"π ≈ {pi:.2f}") # 对齐和填充 num = 42 print(f"{num:0>5}") # 00042 print(f"{num:*^10}") # ****42**** # 调试输出(Python 3.8+) x = 10 print(f"{x=}") # x=10 推荐:新代码统一使用 f-string,简洁且高效。 ...

2024-02-27 · 3 min · 581 words · Hank

Python教程06:控制流程-循环语句

Python 教程 06:控制流程-循环语句 “重复是力量之母。” 如果说条件语句让程序会"选择",那循环语句就让程序会"重复"。想象一下,如果要打印 1 到 100 的数字,难道要写 100 行print()吗?循环语句就是为了解决这类重复性工作而生的。 1. for 循环:遍历序列 for 循环用于遍历序列(列表、字符串、范围等)中的每个元素。 基本语法 # 遍历列表 fruits = ["苹果", "香蕉", "橙子"] for fruit in fruits: print(f"我喜欢吃{fruit}") # 遍历字符串 for char in "Python": print(char) # 遍历字典 user = {"name": "张三", "age": 25, "city": "北京"} for key in user: print(f"{key}: {user[key]}") 语法要点: for 变量 in 序列: 循环体必须缩进 每次循环,变量会依次取序列中的每个值 range()函数 range()生成数字序列,是 for 循环的好搭档。 # range(stop):从0到stop-1 for i in range(5): print(i) # 0, 1, 2, 3, 4 # range(start, stop):从start到stop-1 for i in range(1, 6): print(i) # 1, 2, 3, 4, 5 # range(start, stop, step):指定步长 for i in range(0, 10, 2): print(i) # 0, 2, 4, 6, 8 # 倒序 for i in range(10, 0, -1): print(i) # 10, 9, 8, ..., 1 enumerate():带索引的遍历 有时候需要同时获取元素和索引: ...

2024-01-21 · 3 min · 615 words · Hank

Python教程05:控制流程-条件语句

Python 教程 05:控制流程-条件语句 “人生处处是选择。” 程序和人生一样,也需要做出选择。条件语句就是让程序具备"决策"能力的工具,就像十字路口的红绿灯,告诉你该往哪走。 1. if 语句:单向选择 最简单的条件语句,满足条件就执行,不满足就跳过。 age = 20 if age >= 18: print("你已经成年了") print("可以独立做决定") 语法要点: if后面跟条件表达式,以冒号结尾 条件代码块必须缩进(通常 4 个空格) 缩进的代码属于 if 块,一起执行或跳过 2. if-else:双向选择 两条路,必须选一条。 age = 15 if age >= 18: print("成年人,可以投票") else: print("未成年,不能投票") 就像走到岔路口,往左或往右,总要选一个方向。 3. if-elif-else:多向选择 当选择超过两个时,使用elif(else if 的缩写)。 score = 85 if score >= 90: grade = "A" elif score >= 80: grade = "B" elif score >= 70: grade = "C" elif score >= 60: grade = "D" else: grade = "F" print(f"分数:{score},等级:{grade}") 执行顺序: 从上到下依次判断 遇到第一个为 True 的条件就执行,然后跳出整个 if-elif-else 结构 如果所有条件都是 False,执行 else 块(如果有的话) 这就像走迷宫,找到第一个出口就出去了,不会继续找其他出口。 4. 嵌套条件 条件语句里还可以包含条件语句。 age = 20 has_id = True if age >= 18: if has_id: print("验证通过,可以进入") else: print("请出示身份证") else: print("未成年,不能进入") 注意缩进:每一层嵌套增加一层缩进。 ...

2023-12-06 · 3 min · 501 words · Hank

Python教程04:运算符

Python 教程 04:运算符 “巧妇难为无米之炊。” 有了数据类型,接下来就要学会如何操作这些数据。运算符就是操作数据的工具,就像厨房里的刀、铲、勺,每种工具各有用途。 1. 算术运算符 最基础的运算符,用于数学计算。 基本运算 运算符 说明 示例 结果 + 加法 5 + 3 8 - 减法 5 - 3 2 * 乘法 5 * 3 15 / 除法 5 / 2 2.5 // 整除 5 // 2 2 % 取模(余数) 5 % 2 1 ** 乘方 2 ** 3 8 # 算术运算示例 a = 10 b = 3 print(f"{a} + {b} = {a + b}") # 13 print(f"{a} - {b} = {a - b}") # 7 print(f"{a} * {b} = {a * b}") # 30 print(f"{a} / {b} = {a / b}") # 3.333... print(f"{a} // {b} = {a // b}") # 3 print(f"{a} % {b} = {a % b}") # 1 print(f"{a} ** {b} = {a ** b}") # 1000 有趣的细节 除法的"历史遗留问题" ...

2023-12-04 · 5 min · 861 words · Hank

Python教程03:数据类型基础

Python 教程 03:数据类型基础 “万物皆有类。” 在 Python 的世界里,所有数据都有自己的类型。了解数据类型,就像认识食材,知道哪些能一起烹饪,哪些会"水火不容"。 1. Python 的基础数据类型 Python 有几种基础数据类型,今天我们先学习最常用的四种: 类型 英文名 示例 说明 整数 int 42, -100, 0 没有小数点的数字 浮点数 float 3.14, -0.5, 2.0 带小数点的数字 字符串 str "Hello", 'Python' 文本数据 布尔值 bool True, False 真或假 还有一个特殊的值:None,表示"空"或"无值"。 2. 整数(int) 整数就是没有小数部分的数字,可正可负可为零。 # 整数示例 age = 25 temperature = -10 zero = 0 print(age, type(age)) # 25 <class 'int'> print(temperature) # -10 # Python 3的整数可以无限大(只要内存够) big_number = 1234567890123456789012345678901234567890 print(big_number) # 正常输出,不会溢出 # 不同进制的整数 binary = 0b1010 # 二进制,等于十进制的10 octal = 0o12 # 八进制,等于十进制的10 hexadecimal = 0x1F # 十六进制,等于十进制的31 print(binary, octal, hexadecimal) # 10 10 31 整数运算 a = 10 b = 3 # 基本运算 print(a + b) # 13 加法 print(a - b) # 7 减法 print(a * b) # 30 乘法 # 除法:注意Python 3的除法很特别 print(a / b) # 3.3333... 除法,结果是浮点数 print(a // b) # 3 整除,结果是整数 print(a % b) # 1 取模(求余数) # 乘方 print(a ** 2) # 100 (10的2次方) print(2 ** 10) # 1024 这里有个有趣的现象:在 Python 3 中,10 / 3的结果是3.333...(浮点数),而不是像 Go/Java 那样得到3。如果你想要整除,必须用//。 ...

2023-11-20 · 3 min · 607 words · Hank

Python教程02:基础语法

Python 教程 02:基础语法 “纸上得来终觉浅,绝知此事要躬行。” 学编程和学游泳一样,看再多教程也不如下水扑腾几下。今天我们来学习 Python 的基础语法,这些是写代码的"规矩"。 1. 注释:给代码写"旁白" 注释就像电影里的旁白,是写给人看的,不会被 Python 执行。写注释有两个好处: 提醒自己:三个月后回头看代码,如果没有注释,你可能会问"这是谁写的垃圾代码?"(然后发现是自己写的) 方便别人:团队协作时,注释能让其他人快速理解你的思路 单行注释 用#开头,从#开始到行尾的所有内容都是注释: # 这是一个单行注释 print("Hello") # 这也是注释,可以放在代码后面 # 计算圆的面积 radius = 5 area = 3.14 * radius ** 2 多行注释 Python 没有专门的多行注释语法,但可以用三引号('''或""")来实现: """ 这是一个多行注释 可以写很多行 通常用于写文档字符串(docstring) """ ''' 单引号也可以 但更推荐用双引号 ''' def calculate_area(radius): """ 计算圆的面积 参数: radius: 圆的半径 返回: 圆的面积 """ return 3.14 * radius ** 2 最佳实践:注释要写"为什么",而不是"是什么"。比如# 计算圆的面积这种注释意义不大,因为代码本身已经很清楚了。更好的注释是:# 使用简化的π值,精确度够用且计算更快 2. 缩进:Python 的"规矩" 如果说 C/Java 用大括号{}来组织代码结构,那 Python 用的就是缩进。这是 Python 最独特的地方,也是新手最容易犯错的地方。 ...

2023-11-10 · 3 min · 484 words · Hank

Python教程01:Python简介与环境搭建

Python 教程 01:Python 简介与环境搭建 “工欲善其事,必先利其器。” 在开始学习 Python 之前,我们先要把环境搭建好。别担心,这比组装宜家家具简单多了。 1. Python 是什么? Python 是一种高级编程语言,由荷兰程序员 Guido van Rossum 于 1991 年创建。有趣的是,这个名字并非来自那条盘在树上的蟒蛇,而是源自英国喜剧团体"Monty Python"(蒙提·派森)。Guido 在开发 Python 时正在看这个喜剧团的剧集,觉得这名字"简短、独特、略带神秘",于是就用了。 不过大家还是约定俗成地用蛇做 Logo,毕竟这样看起来更酷一些。 Python 的三大特点 简单易学:语法接近自然语言,读代码就像读英文句子 功能强大:从网站开发到人工智能,从自动化脚本到科学计算,几乎无所不能 生态丰富:拥有数十万个第三方库,就像一个超级大工具箱 用一句话概括:Python 是程序员界的瑞士军刀——简单好用,功能齐全。 2. 为什么学 Python? 应用领域广泛 Web 开发:Django、Flask、FastAPI 框架让你快速搭建网站 数据分析:Pandas、NumPy、Matplotlib 是数据科学家的标配 人工智能:TensorFlow、PyTorch 支撑着深度学习的发展 自动化脚本:批量处理文件、爬虫、运维工具,让重复劳动自动化 游戏开发:Pygame 虽然小众,但也很有趣 科学计算:SciPy 在科研领域广泛应用 市场需求大 根据 TIOBE 编程语言排行榜,Python 常年稳居前三。这意味着无论你是找工作、做副业,还是只是想提升技能,Python 都是一个非常好的选择。 就像学外语,你可以学世界语(优雅但没人用),也可以学英语(实用且吃香)。Python 就是编程界的"英语"。 代码简洁优雅 Python 崇尚"用最少的代码做最多的事"。同样的功能,Python 代码往往比其他语言短 50%以上。比如打印 1 到 10: # Python:简洁明了 for i in range(1, 11): print(i) 非常的简洁。 3. Python 2 vs Python 3:历史的遗留问题 目前 Python 有两个主要版本: ...

2023-10-18 · 2 min · 368 words · Hank