__str__面向用户,返回易读字符串(如"User: alice (id=42)");__repr__面向开发者,要求精确无歧义、 ideally 可 eval 重建(如User("alice", id=42)),容器打印时默认调用__repr__。

__str__ 是给用户看的,__repr__ 是给开发者看的
两者都返回字符串,但定位完全不同:__str__ 应该返回易读、友好的描述(比如 "User: alice (id=42)"),用于 print() 或 str();而 __repr__ 必须尽可能精确、无歧义,理想情况下能直接复制粘贴进 Python 解释器重建对象(比如 User("alice", id=42))。如果只实现一个,优先写 __repr__ —— 它是调试时默认 fallback,__str__ 缺失时会自动调用它。
__repr__ 必须保证可被 eval() 重建(理想情况)
这不是强制要求,但强烈建议。尤其在数据类、模型类或配置对象中,清晰的 __repr__ 能极大提升 debug 效率。常见错误是拼接字符串时漏掉引号、没转义、或用了不可序列化的值(如函数、文件句柄)。
- 正确:
return f"Point(x={self.x!r}, y={self.y!r})"(!r自动加引号并转义) - 错误:
return f"Point({self.x}, {self.y})"(若self.x是字符串"hello",输出变成Point(hello),无法 eval) - 避免在
__repr__中访问数据库、网络或耗时属性 —— 它可能被日志、IDE 变量面板频繁调用
__str__ 可以省略,但别让它和 __repr__ 一模一样
很多初学者图省事,让 __str__ 直接 return self.__repr__()。这会让终端输出充满括号和引号,对终端用户不友好。真正需要的是语义化表达:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 日期对象:
__str__返回"2024-06-15",__repr__返回datetime.date(2024, 6, 15) - 异常对象:
__str__是错误消息("division by zero"),__repr__包含类型和完整参数(ZeroDivisionError('division by zero')) - 如果对象没有自然的“用户视角”描述(比如底层工具类),可以不实现
__str__,让 Python 自动 fallback 到__repr__
在容器里打印时,Python 默认调用 __repr__
这是最容易忽略的一点:当你把对象放进 list、dict 或 set 后打印,比如 print([obj1, obj2]),Python 对每个元素调用的是 __repr__,不是 __str__。所以即使你精心写了友好的 __str__,在列表里依然看到的是调试风格的输出。如果你希望容器显示也“好看”,只能手动处理(例如用列表推导式套 str()),或者接受这个事实 —— 容器的默认行为就是面向开发者的。
复杂点在于:某些框架(如 Pandas、Django ORM)会重载容器的显示逻辑,绕过原生规则。但纯 Python 的 list、dict、set 始终遵守这条规则。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










