Python中访问BowlingGame内Frame属性报错:类型对象无rolls属性
问题分析与解决
核心问题
你在BowlingGame的构造函数里犯了一个关键错误:你把Frame类本身添加到了frames列表中,而不是创建Frame的实例。代码self.frames = [Frame for _ in range(10)]生成的是10个Frame类对象,而非10个Frame实例。
这直接导致:
- 第一个测试误通过:
type(game.frames[0]) == type(Frame)本质是在比较type(Frame)(即type类)和自身,所以结果为True,但这并不是你真正要验证的“列表元素是Frame实例”的逻辑。 - 第二个测试失败:
rolls是Frame实例的属性,仅在实例初始化时被创建,而你试图访问Frame类对象的rolls属性,自然会抛出属性不存在的错误。
修复步骤
1. 修正BowlingGame的构造函数
把类引用改成实例创建,即在Frame后加():
class BowlingGame: def __init__(self) -> None: self.frames = [Frame() for _ in range(10)] # 创建Frame实例存入列表 class Frame: def __init__(self) -> None: self.rolls = [Roll] # 若需存储Roll实例,这里也应改为Roll(),视需求调整 class Roll: pass
2. 修正测试用例的断言逻辑
第一个测试的断言逻辑错误,应验证元素是Frame的实例;第二个测试漏写assert关键字,导致表达式不会被测试框架检查:
from bowling import BowlingGame, Frame game = BowlingGame() def test_game_has_ten_frames(): assert len(game.frames) == 10 assert isinstance(game.frames[0], Frame) # 正确的实例类型检查方式 assert isinstance(game.frames[9], Frame) def test_frame_has_atleast_one_roll(): assert len(game.frames[0].rolls) == 1 # 加上assert才会触发测试验证
额外说明
如果你的rolls列表需要存储Roll的实例(而非Roll类本身),Frame的构造函数也需调整:
class Frame: def __init__(self) -> None: self.rolls = [Roll()] # 创建Roll实例存入列表
内容的提问来源于stack exchange,提问作者Victorio Morello
相关产品推荐
相关产品推荐

