1. 引言
在前几篇文章中,我们已经学习了 Python 的基本语法、数据类型、流程控制和数据结构。今天,我们将进入 Python 编程中更核心的部分:函数与模块、文件操作、异常处理。这三块内容是编写任何实际 Python 程序都绕不开的基础能力------函数让代码可复用,模块让工程可组织,文件操作让程序能与外部数据交互,异常处理则让程序在出错时依然优雅、可控。
学完本篇,你将能够:
- 熟练定义和调用函数,理解参数传递、返回值与作用域;
- 使用模块和包组织代码,导入并使用标准库与第三方库;
- 读写文本文件和二进制文件,掌握文件上下文管理;
- 使用
try/except/finally捕获并处理异常,编写健壮的程序。
2. 函数
2.1 函数的定义与调用
函数是组织好的、可重复使用的代码块。Python 使用 def 关键字定义函数:
python
def greet(name):
"""打印问候语"""
print(f"你好,{name}!")
greet("小明") # 输出:你好,小明!
函数定义以 def 开头,后跟函数名、括号内的参数列表和冒号。函数体需要缩进。函数内的第一行字符串称为文档字符串(docstring),用于说明函数功能。
2.2 参数传递
Python 函数的参数传递非常灵活,支持多种形式:
python
# 位置参数
def add(a, b):
return a + b
print(add(3, 5)) # 8
# 默认参数
def power(base, exp=2):
return base ** exp
print(power(3)) # 9
print(power(3, 3)) # 27
# 关键字参数
def introduce(name, age, city):
print(f"{name},{age}岁,来自{city}")
introduce(age=18, city="北京", name="小红")
# 可变参数 *args
def total(*nums):
return sum(nums)
print(total(1, 2, 3, 4)) # 10
# 关键字可变参数 **kwargs
def show_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
show_info(name="小明", score=95)
注意 :默认参数必须放在非默认参数之后;可变参数 *args 接收元组,**kwargs 接收字典。
参数传递方式对比:
| 参数类型 | 语法示例 | 特点 | 适用场景 |
|---|---|---|---|
| 位置参数 | def add(a, b) |
按位置顺序传参,最基础、最直观 | 参数较少且顺序固定时使用 |
| 默认参数 | def power(base, exp=2) |
调用时可省略,有默认值兜底 | 参数有常用默认值,如配置项、可选开关 |
| 关键字参数 | introduce(age=18, city="北京", name="小红") |
按参数名传参,顺序可打乱,可读性强 | 参数较多时提升可读性,避免记错顺序 |
*args |
def total(*nums) |
接收任意数量的位置参数,打包为元组 | 参数数量不固定,如求和、拼接 |
**kwargs |
def show_info(**kwargs) |
接收任意数量的关键字参数,打包为字典 | 需要灵活接收命名参数,如配置字典、装饰器 |
总结 :在实际开发中,最常用的组合是「位置参数 + 默认参数」------用位置参数保证核心参数的明确性,用默认参数为可选配置提供兜底;当参数数量不确定时再引入 *args 和 **kwargs,而关键字参数则常用于参数较多、需要提升调用可读性的场景。
2.3 返回值
函数使用 return 返回结果。没有 return 的函数返回 None:
python
def get_max(a, b):
return a if a > b else b
def no_return():
pass
print(get_max(10, 20)) # 20
print(no_return()) # None
Python 函数可以返回多个值,实际是返回一个元组:
python
def swap(a, b):
return b, a
x, y = swap(1, 2)
print(x, y) # 2 1
2.4 变量作用域
函数内部定义的变量是局部变量 ,函数外部的是全局变量:
python
count = 10 # 全局变量
def change():
global count # 声明使用全局变量
count = 20
change()
print(count) # 20
在函数内直接赋值同名变量,会创建新的局部变量,不会影响全局变量。使用 global 关键字可以修改全局变量,但应谨慎使用。
2.5 匿名函数 lambda
lambda 用于定义简单的单行匿名函数:
python
square = lambda x: x ** 2
print(square(5)) # 25
# 常与 sorted、map、filter 等配合使用
students = [("小明", 88), ("小红", 95), ("小刚", 72)]
students.sort(key=lambda s: s[1], reverse=True)
print(students) # [('小红', 95), ('小明', 88), ('小刚', 72)]
3. 模块与包
3.1 什么是模块
模块是一个包含 Python 代码的 .py 文件。将相关函数、类和变量组织到模块中,便于代码复用和维护。
3.2 导入模块
Python 提供多种导入方式:
python
# 方式一:导入整个模块
import math
print(math.sqrt(16)) # 4.0
# 方式二:导入特定成员
from math import sqrt, pi
print(sqrt(25)) # 5.0
print(pi) # 3.141592653589793
# 方式三:导入模块并起别名
import numpy as np
import pandas as pd
# 方式四:导入所有成员(不推荐,易污染命名空间)
from math import *
3.3 自定义模块
创建 mymodule.py 文件:
python
# mymodule.py
def hello(name):
return f"Hello, {name}!"
PI = 3.14159
在另一个文件中导入使用:
python
import mymodule
print(mymodule.hello("Python")) # Hello, Python!
print(mymodule.PI) # 3.14159
3.4 包(Package)
包是包含 __init__.py 文件的目录,用于组织多个模块:
myproject/
├── __init__.py
├── utils/
│ ├── __init__.py
│ ├── strings.py
│ └── math_ops.py
└── main.py
导入包内模块:
python
from utils.strings import reverse_str
from utils.math_ops import add
3.5 常用标准库
Python 标准库提供了丰富的功能模块:
python
import os # 操作系统接口
import sys # 系统相关参数
import json # JSON 数据处理
import re # 正则表达式
import random # 随机数
import datetime # 日期时间
import collections # 高级容器类型
# 示例:使用 random 和 datetime
import random
import datetime
print(random.randint(1, 100)) # 随机整数
print(datetime.date.today()) # 当前日期
4. 文件操作
4.1 打开与关闭文件
Python 使用 open() 函数打开文件,返回文件对象:
python
# 打开文件(默认只读模式)
f = open("data.txt", "r", encoding="utf-8")
content = f.read()
f.close() # 记得关闭文件
文件打开模式:
| 模式 | 说明 |
|---|---|
r |
只读(默认),文件必须存在 |
w |
只写,覆盖原内容,文件不存在则创建 |
a |
追加,在文件末尾写入 |
r+ |
读写 |
b |
二进制模式,如 rb、wb |
4.2 使用 with 语句(推荐)
with 语句可以自动管理文件资源,无需手动 close():
python
# 读取文件
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 写入文件
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!\n")
f.write("第二行内容\n")
with 语句 vs 手动 close():
| 对比维度 | with 语句 |
手动 close() |
|---|---|---|
| 资源管理方式 | 自动管理,代码块结束后自动关闭文件 | 需手动调用 f.close(),容易遗漏 |
| 异常安全性 | 即使代码块内抛出异常,文件也会被正确关闭 | 若异常发生在 close() 之前,文件可能无法关闭 |
| 代码简洁度 | 代码更简洁,无需显式写关闭语句 | 需要额外写 close(),代码更冗长 |
| 适用场景 | 推荐用于所有文件读写场景,尤其是需要保证资源释放的场合 | 仅适合极简单的临时脚本,且需确保 close() 一定被执行 |
说明 :with 语句之所以是推荐写法,核心在于它通过上下文管理器(context manager)保证了资源的确定性释放。无论代码块正常执行完毕,还是中途抛出异常,with 都会在退出时自动调用 close(),避免文件句柄泄漏。而手动 close() 一旦遇到异常或提前 return,就很容易跳过关闭语句,导致资源长期占用甚至数据未落盘。因此在实际开发中,应始终优先使用 with 语句来管理文件资源。
4.3 读取文件的多种方式
python
# 读取全部内容
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
# 逐行读取
with open("data.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip() 去除换行符
# 读取所有行到列表
with open("data.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 读取指定字符数
with open("data.txt", "r", encoding="utf-8") as f:
chunk = f.read(100) # 读取前 100 个字符
4.4 文件写入与追加
python
# 覆盖写入
with open("log.txt", "w", encoding="utf-8") as f:
f.write("新内容\n")
# 追加写入
with open("log.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")
# 写入多行
lines = ["第一行", "第二行", "第三行"]
with open("data.txt", "w", encoding="utf-8") as f:
f.writelines(line + "\n" for line in lines)
4.5 文件与目录操作
使用 os 模块操作文件和目录:
python
import os
# 检查文件是否存在
print(os.path.exists("data.txt"))
# 重命名文件
os.rename("old.txt", "new.txt")
# 删除文件
os.remove("temp.txt")
# 创建目录
os.mkdir("newdir")
# 列出目录内容
print(os.listdir("."))
# 获取文件大小
size = os.path.getsize("data.txt")
print(f"文件大小:{size} 字节")
4.6 处理 JSON 文件
JSON 是常用的数据交换格式,Python 的 json 模块可以轻松处理:
python
import json
# 写入 JSON
data = {"name": "小明", "age": 18, "scores": [88, 95, 76]}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 读取 JSON
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["name"]) # 小明
5. 异常处理
5.1 什么是异常
程序运行过程中出现的错误称为异常。如果不处理,程序会中断并显示错误信息:
python
# 示例:除零异常
# print(10 / 0) # ZeroDivisionError: division by zero
# 示例:索引越界
# lst = [1, 2, 3]
# print(lst[5]) # IndexError: list index out of range
5.2 try/except 捕获异常
使用 try/except 捕获并处理异常,让程序继续运行:
python
try:
num = int(input("请输入一个数字:"))
result = 100 / num
print(f"结果是:{result}")
except ZeroDivisionError:
print("错误:不能除以零!")
except ValueError:
print("错误:请输入有效的数字!")
5.3 捕获多种异常
python
try:
# 可能出错的代码
data = [1, 2, 3]
index = int(input("输入索引:"))
print(data[index])
except (IndexError, ValueError) as e:
print(f"发生错误:{e}")
# 捕获所有异常(不推荐,应尽量明确异常类型)
try:
result = 10 / 0
except Exception as e:
print(f"未知错误:{e}")
5.4 else 与 finally
else:没有异常时执行;finally:无论是否异常都会执行,常用于资源清理。
python
try:
f = open("data.txt", "r", encoding="utf-8")
content = f.read()
except FileNotFoundError:
print("文件不存在!")
else:
print("文件读取成功")
print(content)
finally:
print("无论是否出错,这里都会执行")
# f.close() # 关闭文件
5.5 抛出异常 raise
使用 raise 主动抛出异常:
python
def set_age(age):
if age < 0 or age > 150:
raise ValueError("年龄必须在 0-150 之间")
print(f"年龄设置为:{age}")
try:
set_age(200)
except ValueError as e:
print(f"参数错误:{e}")
5.6 自定义异常
可以创建自定义异常类,继承 Exception:
python
class BalanceError(Exception):
"""余额不足异常"""
pass
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise BalanceError(f"余额不足,当前余额:{self.balance}")
self.balance -= amount
print(f"取款成功,剩余余额:{self.balance}")
account = BankAccount(100)
try:
account.withdraw(150)
except BalanceError as e:
print(f"取款失败:{e}")
5.7 异常处理最佳实践与排查思路
掌握了异常的基本语法后,还需要了解一些工程实践,才能写出健壮、易维护的代码。
① 异常捕获粒度建议
尽量捕获具体异常 ,而不是笼统地捕获 Exception。捕获范围越宽,越容易掩盖真正的错误,导致问题难以定位:
python
# 不推荐:范围过宽,掩盖了真实错误
try:
data = json.loads(text)
print(data["name"])
except Exception as e:
print(f"出错了:{e}") # 到底是 JSON 解析失败,还是 KeyError?无从得知
# 推荐:分别捕获具体异常,针对性处理
try:
data = json.loads(text)
print(data["name"])
except json.JSONDecodeError:
print("JSON 格式错误")
except KeyError:
print("缺少 name 字段")
建议 :先列出可能出现的具体异常类型,逐个 except 处理;只有在你确实需要兜底、且明确知道自己在做什么时,才使用 except Exception,并尽量在最后捕获、记录日志后重新抛出或退出。
② 异常链与 raise from
当你在 except 中抛出新的异常时,使用 raise ... from ... 可以保留原始异常信息,形成异常链,方便排查根因:
python
def load_user(filename):
try:
with open(filename, "r", encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError as e:
# 保留原始异常,同时抛出更上层的业务异常
raise ValueError(f"用户数据文件 {filename} 缺失") from e
try:
user = load_user("user.json")
except ValueError as e:
print(f"业务错误:{e}")
print(f"原始原因:{e.__cause__}") # FileNotFoundError
from e 会把原始异常挂到新异常的 __cause__ 属性上,打印 traceback 时能看到完整的调用链,而不是只看到被吞掉的表面错误。
③ 常见异常类型速查表
| 异常类型 | 触发场景 | 典型示例 |
|---|---|---|
FileNotFoundError |
打开不存在的文件 | open("no.txt") |
KeyError |
字典中访问不存在的键 | d["age"],而 d 中没有 "age" |
TypeError |
类型不匹配的操作 | "1" + 1、调用不存在的参数 |
AttributeError |
访问对象不存在的属性/方法 | None.name、"abc".append(1) |
ValueError |
值本身不合法 | int("abc")、float("x") |
IndexError |
列表索引越界 | lst[10],而 lst 只有 3 个元素 |
ZeroDivisionError |
除数为零 | 10 / 0 |
json.JSONDecodeError |
JSON 字符串解析失败 | json.loads("{bad json}") |
④ 排查异常的三步法:复现 → 定位 → 修复
遇到异常不要慌,按下面三步系统排查:
- 复现:拿到完整的报错信息(traceback),找到能稳定触发问题的输入,确保问题可复现;
- 定位 :从 traceback 最底部往上读,找到第一个你自己写的代码所在行,那通常是问题根源;
- 修复:针对根因修改,修复后回归测试,确认不再复现。
下面是一个简单调试示例:
python
# 场景:读取成绩文件并计算平均分
def average_score(filename):
with open(filename, "r", encoding="utf-8") as f:
scores = [float(line.strip()) for line in f]
return sum(scores) / len(scores)
# 运行时报错:ValueError: could not convert string to float: '小明,88'
# 排查三步法:
# 1. 复现:传入 grades.txt,内容为 "小明,88\n小红,95",稳定报错
# 2. 定位:traceback 指向列表推导式 float(line.strip()),发现每行是 "姓名,成绩" 格式
# 3. 修复:先按逗号拆分,再取成绩部分转换
def average_score(filename):
with open(filename, "r", encoding="utf-8") as f:
scores = []
for line in f:
parts = line.strip().split(",")
if len(parts) == 2:
scores.append(float(parts[1]))
return sum(scores) / len(scores) if scores else 0
print(average_score("grades.txt")) # 91.5
小结 :异常处理的核心不是「消灭异常」,而是「在正确的位置、以正确的粒度处理异常」。捕获具体异常、善用 raise from 保留异常链、熟悉常见异常类型、按「复现→定位→修复」三步排查,是写出健壮 Python 程序的关键。
6. 综合示例:学生成绩管理系统
下面综合运用本篇所学知识,实现一个简单的学生成绩管理系统:
python
import json
import os
class Student:
"""学生类"""
def __init__(self, name, scores):
self.name = name
self.scores = scores # 字典,如 {"语文": 88, "数学": 95}
def average(self):
return sum(self.scores.values()) / len(self.scores)
class GradeManager:
"""成绩管理类"""
def __init__(self, filename="students.json"):
self.filename = filename
self.students = []
self.load()
def add_student(self, name, scores):
self.students.append(Student(name, scores))
self.save()
print(f"已添加学生:{name}")
def load(self):
"""从文件加载数据"""
if not os.path.exists(self.filename):
return
try:
with open(self.filename, "r", encoding="utf-8") as f:
data = json.load(f)
self.students = [Student(s["name"], s["scores"]) for s in data]
except (json.JSONDecodeError, KeyError) as e:
print(f"数据文件损坏:{e}")
def save(self):
"""保存数据到文件"""
data = [{"name": s.name, "scores": s.scores} for s in self.students]
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def show_ranking(self):
"""显示成绩排名"""
if not self.students:
print("暂无学生数据")
return
ranked = sorted(self.students, key=lambda s: s.average(), reverse=True)
print("成绩排名:")
for i, s in enumerate(ranked, 1):
print(f"第{i}名:{s.name},平均分:{s.average():.1f}")
def main():
manager = GradeManager()
while True:
print("\n1. 添加学生")
print("2. 查看排名")
print("3. 退出")
choice = input("请选择操作:")
if choice == "1":
name = input("学生姓名:")
scores = {}
for subject in ["语文", "数学", "英语"]:
try:
score = float(input(f"{subject}成绩:"))
scores[subject] = score
except ValueError:
print("成绩输入无效,请重新输入")
continue
manager.add_student(name, scores)
elif choice == "2":
manager.show_ranking()
elif choice == "3":
print("再见!")
break
else:
print("无效选择,请重试")
if __name__ == "__main__":
main()
这个示例综合运用了函数、类、模块、文件操作(JSON 读写)和异常处理,是一个完整的小型应用。
7. 练习题
下面提供 5 道与函数、文件操作、异常处理相关的编程练习题,建议先独立完成,再对照参考答案和解析。
7.1 练习题一:计算器函数
编写一个函数 calculator(a, b, op),根据运算符 op(+、-、*、/)返回两个数的运算结果。要求:当除数为 0 时抛出 ZeroDivisionError,当运算符不支持时抛出 ValueError。
参考答案:
python
def calculator(a, b, op):
if op == "+":
return a + b
elif op == "-":
return a - b
elif op == "*":
return a * b
elif op == "/":
if b == 0:
raise ZeroDivisionError("除数不能为零")
return a / b
else:
raise ValueError(f"不支持的运算符:{op}")
# 测试
print(calculator(10, 5, "+")) # 15
print(calculator(10, 5, "/")) # 2.0
try:
calculator(10, 0, "/")
except ZeroDivisionError as e:
print(f"错误:{e}") # 错误:除数不能为零
try:
calculator(10, 5, "%")
except ValueError as e:
print(f"错误:{e}") # 错误:不支持的运算符:%
解析 :本题综合考查函数定义、条件分支和异常抛出。使用 if/elif/else 判断运算符,对除零和非法运算符分别抛出对应异常,调用方用 try/except 捕获处理。
7.2 练习题二:统计文本文件词频
给定一个文本文件 article.txt,编写程序统计其中每个单词出现的次数,并按出现次数从高到低输出前 5 个单词及其频次(忽略大小写和标点符号)。
参考答案:
python
import re
from collections import Counter
def count_words(filename, top_n=5):
"""统计文件中单词频次,返回前 top_n 个"""
try:
with open(filename, "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print(f"文件 {filename} 不存在")
return []
# 提取单词并统一小写
words = re.findall(r"[a-zA-Z]+", content.lower())
counter = Counter(words)
return counter.most_common(top_n)
# 测试
result = count_words("article.txt")
for word, count in result:
print(f"{word}: {count}")
解析 :本题综合考查文件读取、正则表达式、collections.Counter 和异常处理。用 with 安全读取文件,re.findall 提取纯字母单词并转小写,Counter.most_common 直接按频次排序取前 N 个,同时用 try/except 处理文件不存在的情况。
7.3 练习题三:JSON 配置读取与校验
编写函数 load_config(filename),从 JSON 文件中读取配置,要求配置必须包含 name(字符串)和 version(数字)两个字段。若文件不存在、JSON 格式错误或字段缺失,分别给出明确提示。
参考答案:
python
import json
import os
def load_config(filename):
"""读取并校验 JSON 配置文件"""
if not os.path.exists(filename):
raise FileNotFoundError(f"配置文件 {filename} 不存在")
try:
with open(filename, "r", encoding="utf-8") as f:
config = json.load(f)
except json.JSONDecodeError:
raise ValueError(f"配置文件 {filename} 不是合法的 JSON 格式")
if "name" not in config or not isinstance(config["name"], str):
raise KeyError("配置缺少字符串字段 name")
if "version" not in config or not isinstance(config["version"], (int, float)):
raise KeyError("配置缺少数字字段 version")
return config
# 测试
try:
cfg = load_config("config.json")
print(f"配置加载成功:{cfg}")
except (FileNotFoundError, ValueError, KeyError) as e:
print(f"配置加载失败:{e}")
解析 :本题综合考查 os 模块、JSON 读写、类型校验和多种异常处理。先检查文件是否存在,再捕获 JSON 解析错误,最后用 isinstance 校验字段类型,调用方用元组形式一次捕获多种异常。
7.4 练习题四:日志记录器
编写一个日志记录函数 log_message(message, level="INFO"),将日志以 时间 [级别] 消息 的格式追加写入 app.log 文件。要求:使用 with 语句管理文件,level 只允许 INFO、WARNING、ERROR 三种取值,否则抛出 ValueError。
参考答案:
python
import datetime
def log_message(message, level="INFO"):
"""将日志追加写入 app.log 文件"""
valid_levels = ("INFO", "WARNING", "ERROR")
if level not in valid_levels:
raise ValueError(f"无效的日志级别:{level},可选值:{valid_levels}")
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_line = f"{timestamp} [{level}] {message}\n"
with open("app.log", "a", encoding="utf-8") as f:
f.write(log_line)
# 测试
log_message("程序启动")
log_message("磁盘空间不足", level="WARNING")
log_message("数据库连接失败", level="ERROR")
try:
log_message("测试", level="DEBUG")
except ValueError as e:
print(f"错误:{e}")
解析 :本题综合考查函数默认参数、datetime 模块、文件追加写入和 raise 抛异常。用 a 模式追加写入保证不覆盖历史日志,strftime 格式化时间戳,非法级别通过 raise ValueError 主动拦截。
7.5 练习题五:学生成绩统计(综合)
编写程序 grade_stats.py,从 grades.txt 文件中读取学生成绩(每行格式为 姓名,成绩),计算并输出:总人数、平均分、最高分和最低分。要求:文件不存在时给出友好提示,成绩无法转换为数字时跳过该行并记录错误行数。
参考答案:
python
def analyze_grades(filename):
"""分析成绩文件,返回统计结果"""
try:
with open(filename, "r", encoding="utf-8") as f:
lines = f.readlines()
except FileNotFoundError:
print(f"错误:文件 {filename} 不存在")
return
scores = []
error_lines = 0
for line in lines:
line = line.strip()
if not line:
continue
parts = line.split(",")
if len(parts) != 2:
error_lines += 1
continue
name, score_str = parts
try:
score = float(score_str)
scores.append(score)
except ValueError:
error_lines += 1
print(f"跳过无效成绩:{line}")
if not scores:
print("没有有效的成绩数据")
return
print(f"总人数:{len(scores)}")
print(f"平均分:{sum(scores) / len(scores):.1f}")
print(f"最高分:{max(scores)}")
print(f"最低分:{min(scores)}")
if error_lines:
print(f"跳过无效行数:{error_lines}")
# 测试
analyze_grades("grades.txt")
解析 :本题是综合实战题,融合文件读取、字符串处理、异常捕获和内置函数 max/min/sum。外层 try/except 处理文件不存在,内层 try/except 处理单行成绩转换失败,用 error_lines 统计无效行数,体现分层异常处理的思路。
8. 总结
本篇我们学习了 Python 编程的三大核心能力:
- 函数与模块 :
def定义函数、参数传递、返回值、作用域、lambda匿名函数;模块导入、自定义模块、包组织、标准库使用。 - 文件操作 :
open()打开文件、with上下文管理、读写文本与 JSON 文件、os模块操作文件和目录。 - 异常处理 :
try/except捕获异常、else/finally子句、raise抛出异常、自定义异常类。
掌握这些内容后,你已经具备了编写实际 Python 程序的基础能力。建议动手实践:写一个自己的小工具,比如待办事项管理器、通讯录或日志分析脚本,将函数、文件操作和异常处理结合起来使用,才能真正融会贯通。
下一篇我们将继续深入 Python 的面向对象编程,敬请期待!
动手实践建议:
下面给出 3 个具体的综合练习项目,建议结合第 6 章综合示例的代码结构(类封装 + 文件读写 + 异常处理 + 主循环)独立完成:
-
待办事项管理器 :核心功能是支持添加、查看、标记完成和删除待办事项,并将数据持久化到 JSON 文件。涉及函数封装、
json模块读写、try/except处理文件损坏或输入异常,可参考第 6 章中GradeManager类的load/save模式。 -
通讯录程序 :核心功能是管理联系人(姓名、电话、邮箱),支持增删改查并保存到文本或 JSON 文件。涉及类与对象、文件读写、输入校验(如手机号格式、邮箱格式),可参考第 6 章中
Student类与主循环交互的设计思路。 -
日志分析脚本 :核心功能是读取日志文件,统计各错误级别(INFO/WARNING/ERROR)的出现次数,并输出 TOP N 高频错误信息。涉及正则表达式提取、
collections.Counter统计、文件操作,可参考第 7 章练习题二的词频统计思路,将re.findall与Counter.most_common结合使用。