学径XUEJING · 个人学习平台通知设置

课程库 AI 主线 面向对象初步 › 第 5

单元测验:设计一个"待办任务"类

里程碑45 分钟

本课导读

U1.2 关卡,两关制:第一关综合测验 10 题,覆盖本单元四课;第二关设计挑战——从零写一个 TodoList 类(配上 Task),这是全课程第一个完全由你建模的对象系统,也是第一课那个"字典版待办"的正式复仇。通过标准:测验全对 + 挑战代码跑通验收清单。预计 45 分钟。

赛前热身:本单元的知识地图

一句话回顾
1. 为什么需要类字典三痛(拼错静默/数据行为分离/创建无模板);类=模具,对象=产品
2. 类与对象__init__ 出厂设置;self="我";属性声明齐;__str__ 说人话
3. 继承的直觉class B(A) 只写不同;覆盖+super();"是一种"才继承,"有一个"用组合
4. 读懂别人的类三问:怎么造/有什么/会什么;括号分名词动词;type/dir/help 三板斧

第一关:综合测验

随堂测验0 / 10 题正确

1. task["donee"] = True(键拼错)和 task.donee 读取(属性拼错)的行为差别是?

2. t = Task("写周报") 执行时,谁被自动调用?

3. 方法定义里 self.count 和裸写 count 的本质区别是?

4. ada.report() 和 Trainee.report(ada) 的关系是?

5. class Ebook(Book): 里,Ebook 没写 __init__ 也没写 open(),调用 e.open() 会怎样?

6. 子类 __init__ 里第一行写 super().__init__(name) 的原因是?

7. “汽车和发动机”“管理员和用户”,正确的建模组合是?

8. 文档里写 replace(month=12) -> date,而 sort() -> None,说明什么?

9. 拿到一个陌生对象 obj,最合理的探索顺序是?

10. print(w) 输出了友好的中文介绍而不是 <__main__.Wallet object at 0x...>,说明这个类?

第二关:设计挑战——待办任务类

第一课开头那个字典版待办工具,现在用整单元的功夫正式重写。需求文档如下:

Task 类

  • 造:Task(title, priority=2);属性 title、priority、done(初始 False)
  • finish():标记完成
  • __str__:形如 ⬜ 写周报(P2),完成的显示

TodoList 类(持有一批 Task——想想第三课:这是继承还是组合?)

  • 造:TodoList(owner);属性 owner 和 tasks(初始空列表)
  • add(title, priority=2):新建一个 Task 放进列表
  • pending():返回所有未完成任务的列表(推导式的活)
  • summary():返回形如 小雨的待办:3 项,还剩 2 项未完成

验收清单(写完逐条对照):

  • 两个类的属性全部在 __init__ 里声明齐
  • 造一个清单、add 三项、finish 其中一项后,pending() 恰好剩两项
  • print(任务对象)print(清单.summary()) 输出符合格式
  • TodoList 用的是组合(持有 Task 列表),不是继承
Python
💡 提示(卡住再看)

TodoList 的 add 里就一行半:self.tasks.append(Task(title, priority))——类里当然可以造另一个类的对象。pending 是 [t for t in self.tasks if not t.done]。summary 里未完成数就是 len(self.pending())——方法可以调用自家方法。

✅ 参考实现(先自己写完再对照)
class Task:
    def __init__(self, title, priority=2):
        self.title = title
        self.priority = priority
        self.done = False

    def finish(self):
        self.done = True

    def __str__(self):
        mark = "✅" if self.done else "⬜"
        return f"{mark} {self.title}(P{self.priority})"


class TodoList:
    def __init__(self, owner):
        self.owner = owner
        self.tasks = []                  # 组合:持有一批 Task

    def add(self, title, priority=2):
        self.tasks.append(Task(title, priority))

    def pending(self):
        return [t for t in self.tasks if not t.done]

    def summary(self):
        return f"{self.owner}的待办:{len(self.tasks)} 项,还剩 {len(self.pending())} 项未完成"


todo = TodoList("小雨")
todo.add("写周报")
todo.add("订会议室", priority=1)
todo.add("回邮件", priority=3)
todo.tasks[0].finish()
print(todo.summary())
for t in todo.pending():
    print(t)

对照读点:TodoList 持有 Task(组合,"有一批"而非"是一种");pending 是推导式 + 属性判断;summary 复用自家的 pending()。和第一课的字典版摆在一起看——同样的功能,结构的清爽度已是两个时代。

提示

彩蛋练法:把你的实现发给 AI,请它"用陌生类三问审查这两个类,并按 PEP8 和面向对象最佳实践点评"。上一课你学了怎么审 AI,这次让 AI 审你——攻防都练过,功夫才算上身。

通关小结

这一关拿下,你的建模能力完成了一次换代:

  • 诊断力:知道字典建模什么时候会痛、痛在哪,该切换到类时不犹豫
  • 建造力__init__/self/属性/方法/__str__ 一套齐活,还能让两个类组合协作
  • 阅读力:三问 + 三板斧,文档、源码、AI 产出都能拆——这是转行者最高频的实战技能

下个单元离开"语言功夫",进入"干活功夫":文件与自动化脚本——你的 Python 第一次伸手碰真实世界的文件、CSV 和 JSON。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…