在 Python 的对象模型中,字符串表示协议(String Representation Protocol)定义了对象如何以字符串形式表达自身。
这是 Python 面向对象设计中极具 Pythonic 特征的一环——任何对象都应能用字符串清晰地“自我描述”。
该协议由两个核心特殊方法构成:__str__() 与 __repr__()。
前者用于人类可读的输出,后者用于开发与调试中的精确表示。
一、什么是字符串表示协议
在 Python 的哲学中,“一切皆对象”,对象不仅要能被操作,也应能被表达。
字符串表示协议正是为此而生,它定义了对象在以下情境下的行为:
当对象被传递给 print() 或 str()。
当对象出现在解释器交互模式下。
当对象被格式化为字符串。
当使用 repr() 函数或调试输出时。
Python 为此设计了两种不同层面的字符串表示:
__str__() → 提供用户友好的、可读性强的描述。
__repr__() → 提供开发者友好的、可再现的表示。
“字符串表示协议”虽未正式被官方命名,但普遍存在于语言机制与实践中,是事实上的协议。
二、字符串表示协议的核心方法
1、__repr__(self)
返回对象的官方字符串表示(official string representation)。
其目标是尽可能精确、明确,并在理想情况下可以被 eval() 重新构造出原对象。
print(repr(p)) # 输出:Point(2, 3)在标准的 Python 交互模式中,__repr__() 会自动被调用:
Point(2, 3)2、__str__(self)
返回对象的非正式字符串表示(informal string representation)。
其目标是面向用户、可读性优先,不要求能精确重建对象。
print(p) # 调用 __str__(),输出:(2, 3)若类未定义 __str__(),Python 会自动回退到 __repr__() 的结果。
三、两者的区别与调用关系
![]()
也就是说:
__repr__() 是开发者的视角;__str__() 是用户的视角。
示例:同时定义两者
print(repr(v)) # 输出:Vector(1, 2, 3)四、与格式化和调试的关系
(1)字符串格式化
当对象被用于 f-string、format() 或 % 运算时:
• 默认调用 __format__()(若未定义,则使用 __str__())。
• 格式说明符 !r 强制使用 __repr__()。
• 格式说明符 !s 强制使用 __str__()。
print(f"{i!s}") # Item(str)(2)日志与调试输出
调试和日志系统通常偏好使用 repr(),例如 logging 模块或异常堆栈输出中的对象表示。
五、默认行为与自定义策略
如果类没有定义这两个方法,Python 默认继承自 object:
print(repr(Demo())) # <__main__.Demo object at 0x000001>这类默认表示主要用于调试,包含类名与内存地址。
因此,为自定义类实现友好的 __repr__() 和 __str__() 是良好的编码实践。
常见设计建议如下:
若只能定义一个方法 → 定义 __repr__(),因为它更通用;
保证 __repr__() 可重建对象或至少信息充分;
保证 __str__() 可读性好、语义清晰;
避免 __repr__() 中调用 __str__(),防止递归风险。
小结
字符串表示协议是 Python 对象模型中最直观、最常见的协议之一,它让所有对象都能以字符串形式清晰地表达自身,为调试、日志、交互式编程提供了统一接口。
__repr__() 提供开发者视角的精确表示。
__str__() 提供用户视角的可读表示。
若未定义 __str__(),会自动回退到 __repr__()。
两者在交互模式、print()、日志、格式化等场景中各司其职。
为自定义类实现清晰的字符串表示是 Pythonic 风格的重要体现。
“点赞有美意,赞赏是鼓励”
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.