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 二进制模式,如 rbwb

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 只允许 INFOWARNINGERROR 三种取值,否则抛出 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.findallCounter.most_common 结合使用。

相关推荐
小叶肥辉2 小时前
LangChain链和LangGraph图的学习笔记【四】——(1)调用方法:invoke(2)提示语模板:PromptTemplate
python·langchain·prompt
lv__pf2 小时前
09-深入理解AQS之独占锁ReentrantLock源码分析【TL 并发 09】
java·开发语言
小兔崽子去哪了2 小时前
深度学习 2 / CNN 神经网络
后端·python
weixin_440730502 小时前
队列QUEUE介绍+类型示例(先进先出、后进先出、优先级高先出、双端进入、生产者+消费者线程)
python·线程·queue
这是程序猿2 小时前
Java线程池深度剖析:源码原理、核心参数、任务调度与生产调优实战
java·开发语言·python
Web3&Basketball2 小时前
ChatGPT 路由自证:跨客户端实测对照
python·大模型·agent·推理·推理优化
Patrick在香港2 小时前
Claude 工作提醒自动化:香港天文台四个接口三个「更新时间」,警告到期了却还在生效
python·api·claude·数据抓取·香港
用户8356290780512 小时前
Python 实现 Word 文档域的插入与管理
后端·python
quantdash_cc2 小时前
从数据采集到策略消费,股票日内行情管道应该怎么设计?
开发语言·python·数据分析·量化交易·股票数据·quantdash