__repr__ 必须返回可执行字符串以支持对象重建和调试,应包含类名与关键参数;__str__ 则需简洁可读、面向用户,避免调用 __repr__ 或暴露内部结构。

__str__ 和 __repr__ 不是“优化调试输出”的万能开关,它们的职责根本不同:前者面向人,后者面向开发者——混用或只实现一个,反而会让 print(obj) 或 repr(obj) 返回意外结果,甚至干扰日志、logging 模块或 IPython 的显示逻辑。
为什么 __repr__ 必须返回可执行字符串?
Python 的 repr() 本意是生成“能重建对象”的字符串。如果 __repr__ 返回模糊描述(比如 "User object"),你在调试时就无法快速判断对象状态,更没法在 REPL 里复制粘贴验证。
- 理想情况:
__repr__应包含类名 + 关键参数,且参数顺序与__init__一致,例如User(name='alice', age=30) - 避免使用
str(self.__dict__)—— 它会暴露私有属性、方法、未初始化字段,还可能因循环引用崩溃 - 若对象不可重建(如含文件句柄、socket),至少保证唯一性:加入
id(self)或哈希片段,例如User(0x7f8a1c2b3e40)
__str__ 要简洁、可读、无歧义
__str__ 是给终端用户或日志看的,不是给 Python 解析器看的。它不该试图还原构造过程,也不该暴露内部结构。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 优先返回业务语义明确的短字符串,比如
__str__返回"Alice (30 years old)",而不是"name=alice, age=30, active=True" - 不要在
__str__里调用__repr__—— 这会让print()输出变成一堆括号和引号,失去可读性 - 如果对象没有自然“文本表示”(比如一个抽象基类实例),直接
raise NotImplementedError比返回空字符串更诚实
常见错误:把 __repr__ 当成 __str__ 的备选
很多代码写成:def __repr__(self): return self.__str__()。这会导致两个问题:
- IPython/Jupyter 在变量单独一行时自动调用
__repr__,结果看到的是面向用户的字符串,丢失关键调试信息 -
logging.debug("user: %r", user)中的%r会触发__repr__,此时你期望看到的是内存地址或参数快照,而不是“Alice (30 years old)” - 单元测试中用
assert str(obj) == "..."很脆弱 ——__str__可能随 UI 需求变化,但__repr__应该稳定
真正难的不是写这两个方法,而是每次新增字段时同步更新它们——尤其当字段有嵌套、None 或自定义类型时。__repr__ 里漏掉一个关键字段,可能让线上问题排查多花半小时。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










