第一年 · 第14周
第十四章:队伍、列表、循环和你自己的类
上周你为对象添加了方法——attack、heal、show_stats。本周你将把这些对象放入列表、循环遍历队伍、运行一场完整的战斗。然后在第五课时,你将从零开始设计属于你自己的类。
第四课时:队伍、列表和循环
时长:60 分钟
学习目标
- 将多个对象存储在列表中
- 用循环遍历对象列表,并对每个对象调用方法
- 调试常见错误:
self缺失、缺少括号()、变量名不一致
组建队伍(15分钟)
有了类之后,你可以创建任意多个对象,把它们存在列表里——就像存其他值一样:
team = [
Pokemon('Pikachu', 100, 20),
Pokemon('Charmander', 90, 18),
Pokemon('Squirtle', 95, 15),
]
# 循环遍历队伍,打印属性
for p in team:
print(p) # 使用 __str__
# 找到 HP 最高的宝可梦
strongest = team[0]
for p in team:
if p.hp > strongest.hp:
strongest = p
print(f'最强的是: {strongest.name}') 简单战斗模拟(25分钟)
现在我们来搭建一个简单的两队对战。一步一步跟着做:
import random team_a = [Pokemon('Pikachu', 100, 20), Pokemon('Eevee', 80, 15)] team_b = [Pokemon('Geodude', 70, 25), Pokemon('Onix', 90, 22)] def alive(team): return [p for p in team if p.hp > 0] round_num = 1 while alive(team_a) and alive(team_b): print(f'--- 第 {round_num} 回合 ---') attacker = random.choice(alive(team_a)) defender = random.choice(alive(team_b)) attacker.attack(defender) if alive(team_b): # team_b 反击 attacker2 = random.choice(alive(team_b)) defender2 = random.choice(alive(team_a)) attacker2.attack(defender2) round_num += 1 if alive(team_a): print('A队获胜!') else: print('B队获胜!')
调试诊所(15分钟)
老师有一段有 bug 的战斗代码,里面有三个错误。和搭档比赛,看谁先找到并修复所有错误。Bug 藏在:
- 方法定义中缺少
self - 方法调用时缺少
() - 循环变量名使用不一致
出口票
for p in team: p.show_stats()做了什么?- 为什么我们用
alive(team_a)函数,而不是直接在while条件里检查 HP?
第五课时:设计你自己的类
时长:60 分钟
学习目标
- 选择主题,在纸上设计类,再写代码
- 独立实现一个类,包含
__init__、4 个方法和__str__ - 向搭档解释你的设计
先设计——不要碰键盘!(15分钟)
编写代码(35分钟)
把你的对象卡片变成一个能运行的 Python 类。要求:
__init__设置全部 4 个属性- 4 个方法——至少 2 个必须使用
if __str__返回一行美观的摘要- 至少一个方法必须接收一个参数(从外部传入的值)
- 创建 2 个对象,调用至少 3 个方法
起始代码
复制下面的骨架,把 ____ 替换成你自己的内容:
class ________: # ← 填入你的主题名 def __init__(self, name, _____, _____, _____): self.name = name # TODO: 设置你的其他 3 个属性 def method_1(self): # TODO: 写一个简单动作 pass def method_2(self): # ← 必须用 if # TODO: 写一个包含 if/else 的方法 pass def method_3(self, target): # ← 接收参数 # TODO: 写一个操作 target 的方法 pass def method_4(self): # ← 必须用 if # TODO: 再写一个包含 if/else 的方法 pass def __str__(self): return f'...' # TODO: 返回美观的一行摘要
分步指南
- 第 1 步:选一个主题名,把
class ________:改成你自己的类名(如Dragon)。 - 第 2 步:填写
__init__的参数和属性。想想你的对象需要记住哪些信息。 - 第 3 步:写
method_1——一个简单的动作,比如roar()(咆哮)或celebrate()(庆祝)。 - 第 4 步:写
method_2——必须包含if。比如"如果 HP 太低,就恢复一些"。 - 第 5 步:写
method_3——接收一个target参数。比如攻击另一个对象。 - 第 6 步:写
method_4——也必须包含if。比如"如果年龄够大,能力就提升"。 - 第 7 步:写
__str__,用 f-string 返回一行摘要。 - 第 8 步:创建 2 个对象,调用至少 3 个方法测试。
显示完整示例(Dragon 类)
class Dragon: def __init__(self, name, fire_power, hp, age): self.name = name self.fire_power = fire_power self.hp = hp self.age = age def breathe_fire(self, target): target.hp -= self.fire_power if target.hp <= 0: print(target.name, '被击败了!') def rest(self): if self.hp < 100: self.hp += 20 print(f'{self.name} 休息并恢复了 HP。') else: print(f'{self.name} 已经满 HP 了!') def grow_up(self): self.age += 1 if self.age >= 10: self.fire_power += 5 print(f'{self.name} 长大了!火焰威力提升了。') def roar(self): print(f'{self.name} 咆哮了一声!') def __str__(self): return f'{self.name} (年龄: {self.age}, HP: {self.hp}, 火焰: {self.fire_power})' # 创建 2 个对象并测试 draco = Dragon('Draco', 30, 80, 9) smoky = Dragon('Smoky', 25, 90, 11) print(draco) draco.breathe_fire(smoky) print(smoky) draco.rest() draco.grow_up()
展示与讲解(10分钟)
每位同学打开 Thonny,在 Python Shell 中演示一个方法。全班提问:"这个方法做了什么?如果运行两次会怎样?"
出口票
写下一件今天觉得简单的事,和一件觉得困惑的事。