Python 基础语法(六):函数与模块、文件操作、异常处理

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}")
④ 排查异常的三步法:复现 → 定位 → 修复

遇到异常不要慌,按下面三步系统排查:

  1. 复现:拿到完整的报错信息(traceback),找到能稳定触发问题的输入,确保问题可复现;
  2. 定位 :从 traceback 最底部往上读,找到第一个你自己写的代码所在行,那通常是问题根源;
  3. 修复:针对根因修改,修复后回归测试,确认不再复现。

下面是一个简单调试示例:

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 章综合示例的代码结构(类封装 + 文件读写 + 异常处理 + 主循环)独立完成:

  1. 待办事项管理器 :核心功能是支持添加、查看、标记完成和删除待办事项,并将数据持久化到 JSON 文件。涉及函数封装、json 模块读写、try/except 处理文件损坏或输入异常,可参考第 6 章中 GradeManager 类的 load/save 模式。

  2. 通讯录程序 :核心功能是管理联系人(姓名、电话、邮箱),支持增删改查并保存到文本或 JSON 文件。涉及类与对象、文件读写、输入校验(如手机号格式、邮箱格式),可参考第 6 章中 Student 类与主循环交互的设计思路。

  3. 日志分析脚本 :核心功能是读取日志文件,统计各错误级别(INFO/WARNING/ERROR)的出现次数,并输出 TOP N 高频错误信息。涉及正则表达式提取、collections.Counter 统计、文件操作,可参考第 7 章练习题二的词频统计思路,将 re.findall 与 Counter.most_common 结合使用。

相关推荐
风早爽太10 分钟前
Python 学习笔记:SQLModel 使用外键关联查询数据
python·fastapi·sqlmodel
专业程序开发源11 分钟前
springboot社区养老系统44071-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
Dovis(誓平步青云)37 分钟前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
在世修行1 小时前
干货:左右分栏调试工具设计
python·调试设计
sunshine22 girl1 小时前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习
零基础1231 小时前
DeepSeek V4.1 Flash (Batch) 的性能测试与应用
经验分享·python·语言模型·vllm
Yyyyyy~1 小时前
【Anaconda】安装
人工智能·python
LOVE️YOU1 小时前
Python 函数名、函数对象与“把函数作为参数传递”
开发语言·python
2601_957883841 小时前
2026年9月:雷神笔记本售后相关资讯
python·电脑
sunshine22 girl2 小时前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习