
当列表中存储的是自定义类实例时,直接 print 会显示内存地址;需为类实现 __repr__(或 __str__)方法,明确返回可读字符串,才能使列表输出显示对象的有意义值(如分数)。
当列表中存储的是自定义类实例时,直接 print 会显示内存地址;需为类实现 `__repr__`(或 `__str__`)方法,明确返回可读字符串,才能使列表输出显示对象的有意义值(如分数)。
在 Python 中,print(pieter.grades) 输出类似 [<__main__.grade object at>, ...] 的结果,并非 bug,而是默认行为:Python 对列表调用 repr() 时,会递归对每个元素调用其 __repr__ 方法;而 Grade 类未定义该方法,因此使用父类 object 的默认实现——仅返回类型名与内存地址。
要让 print(pieter.grades) 显示 [100, 89] 这样的直观结果,关键在于为 Grade 类正确实现 __repr__ 方法:
class Grade:
minimum_passing = 65
def __init__(self, score):
self.score = score
def is_passing(self):
if self.score >= self.minimum_passing:
print("Passing")
else:
print("Failing")
def __repr__(self):
return f"{self.score}" # ✅ 返回字符串形式的分数值
⚠️ 注意事项:
- __repr__ 应返回无歧义、利于调试的字符串,通常建议可被 eval() 安全解析(本例中 f"{self.score}" 简洁且符合惯例);
- 若同时定义 __str__,print() 优先使用 __str__,但 list.__repr__()(即 print([obj]))仍依赖 __repr__ —— 因此此处必须实现 __repr__;
- 错误示例中注释掉的 __repr__ 写法 return str(self.grades) 是无效的(self.grades 在 Grade 实例中根本不存在),会导致 AttributeError;
- 使用 isinstance(grade, Grade) 替代 type(grade) is Grade 更符合 Python 最佳实践(支持继承)。
完成上述修改后,运行以下代码:
pieter.add_grade(Grade(100)) pieter.add_grade(Grade(89)) print(pieter.grades) # 输出:[100, 89]
即可获得预期结果。本质上,__repr__ 是对象的“官方字符串表示”,它决定了该对象在容器中被展示时的形态。掌握这一机制,是写出可读、可调试 Python 类的关键基础。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











