← 返回 Day 43 正文

Day 43 · 练习与清单

Day 43 完成清单

今日学习:数据类(dataclass)

每个知识点请至少看完对应代码并理解后再勾选 ✅

概念理解

代码实践


练习题

练习 1:最短 dataclass

用 @dataclass 定义一个 Book 类,包含以下字段: - title: str(必填) - author: str(必填) - year: int(可选,默认 2024) - isbn: str(可选,默认空字符串)

要求: - 提供友好的 __repr__(用自动生成的) - 两个相同内容的 Book 实例应该相等(用自动生成的)

python
# 你的代码
from dataclasses import dataclass

@dataclass
class Book:
    ...

练习 2:带验证的学生类

用 @dataclass 定义一个 Student 类,使用 __post_init__ 做以下验证:

python
@dataclass
class Student:
    name: str
    age: int
    grades: list[int]   # 成绩列表
    average: float = field(init=False)  # 自动计算

    def __post_init__(self):
        # TODO:
        # 1. 年龄必须在 6-100 之间
        # 2. 成绩列表不能为空
        # 3. 每个成绩必须在 0-100 之间
        # 4. 自动计算 average(平均分,保留两位小数)

练习 3:订单管理系统

用 @dataclass 实现一个订单管理系统: - OrderItem: 商品名称、数量、单价 - Order: 订单号(自动生成 UUID 前 8 位)、商品列表、总金额(自动计算)

要求: - OrderItem 支持比较(只按单价比较) - Order 的 frozen=True,确保订单创建后不可修改 - Order 的 __repr__ 隐藏商品列表(只显示订单号和金额)

python
from dataclasses import dataclass, field
from typing import List

@dataclass(order=True)
class OrderItem:
    ...

@dataclass(frozen=True)
class Order:
    ...

练习 4:dataclass vs namedtuple 重构

将以下 namedtuple 重构为 dataclass,并添加缺失功能:

python
from typing import NamedTuple

class Employee(NamedTuple):
    name: str
    department: str
    salary: float

# 请重构为 dataclass,并添加:
# 1. 新增 employee_id 字段(自动生成,UUID 前 8 位,不在 __init__ 中)
# 2. 薪资验证(必须 > 0)
# 3. 年薪计算属性:annual_salary
# 4. repr 隐藏 employee_id(只显示姓名和部门)

练习 5:配置验证器

扩展课堂的配置管理系统,新增 CacheConfig 配置块:

python
@dataclass
class CacheConfig:
    backend: str = "memory"     # memory / redis / memcached
    ttl: int = 300               # 缓存过期时间(秒)
    max_size: int = 1000         # 最大缓存条目数
    namespace: str = "default"

    def __post_init__(self):
        # TODO:
        # 1. backend 必须是 "memory", "redis", "memcached" 之一
        # 2. ttl 必须在 1-86400 之间(1秒到1天)
        # 3. max_size 必须在 10-100000 之间

然后将 CacheConfig 整合到 AppConfig 中(在 04-config-manager.py 基础上修改)。

练习 6:实战挑战 —— 序列化工具

写一个通用的 dataclass 序列化工具函数,支持:

python
def dataclass_to_dict(obj) -> dict:
    """
    将 dataclass 递归转换为普通字典。
    处理嵌套 dataclass、列表、可选值。
    隐藏 repr=False 的字段。
    """
    ...

def dict_to_dataclass(cls, data: dict):
    """
    将字典递归还原为 dataclass 实例。
    处理嵌套 dataclass。
    """
    ...

应用场景:读取 config.json → 转换为配置 dataclass → 修改 → 保存回 config.json。


完成标准


附加资源