单元测验:设计一个"待办任务"类
里程碑约 45 分钟
本课导读
U1.2 关卡,两关制:第一关综合测验 10 题,覆盖本单元四课;第二关设计挑战——从零写一个 TodoList 类(配上 Task),这是全课程第一个完全由你建模的对象系统,也是第一课那个"字典版待办"的正式复仇。通过标准:测验全对 + 挑战代码跑通验收清单。预计 45 分钟。
赛前热身:本单元的知识地图
| 课 | 一句话回顾 |
|---|---|
| 1. 为什么需要类 | 字典三痛(拼错静默/数据行为分离/创建无模板);类=模具,对象=产品 |
| 2. 类与对象 | __init__ 出厂设置;self="我";属性声明齐;__str__ 说人话 |
| 3. 继承的直觉 | class B(A) 只写不同;覆盖+super();"是一种"才继承,"有一个"用组合 |
| 4. 读懂别人的类 | 三问:怎么造/有什么/会什么;括号分名词动词;type/dir/help 三板斧 |
第一关:综合测验
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 列表),不是继承
💡 提示(卡住再看)
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。
划选正文任意文字可高亮、批注或加入复习卡
讨论
载入中…