跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何在Python类中定义字符串表示形式_重写__str__与__repr__魔法方法

print(obj) 输出内存地址是因为未重写__str__和__repr__;__str__面向用户,需简洁可读(如"张三(28岁)"),返回str且不拼接敏感信息;__repr__面向开发者,应尽可能可重建对象(如"Person(name='张三', age=28)"),缺失时不会fallback到__str__。 为什么 print(obj) 输出的是
<__main__.Person object at 0x...>
? 因为没重写
__str__
和
__repr__
,Python 默认用内存地址生成字符串。这在调试和日志里完全没法读——你看到的不是“张三,28岁”,而是一串无意义的地址。
__str__
该返回什么?面向谁?
__str__
是给人看的,要简洁、可读、带业务语义。它不负责还原对象,也不需要唯一性。 返回类型必须是
str
,否则会报
TypeError: __str__ returned non-string
别拼接敏感字段(比如密码、token),
__str__
可能被日志系统自动采集 避免调用耗时操作(如数据库查询、文件读取),print 一下就卡住很常见 示例:
def __str__(self):
return f"{self.name}({self.age}岁)"
__repr__
不只是“更详细的
__str__
”
__repr__
面向开发者和调试器,目标是“尽可能还原对象”。理想情况下,
eval(repr(obj)) == obj
应成立(虽常因模块路径、不可序列化对象而妥协)。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 优先包含类名、关键属性,用括号包裹,属性间用逗号分隔(符合 Python 字面量风格) 字符串属性值必须加引号,否则
eval
会报
NameError
如果对象不可重建(如含
threading.Lock
),至少保证输出唯一、可定位,比如加上
id(self)
或哈希 示例:
def __repr__(self):
return f"Person(name='{self.name}', age={self.age})"
两个方法都缺时,
__repr__
会自动 fallback 到
__str__
吗? 不会。只有
__str__
缺失时,
print()
和
str()
才会退回到
__repr__
;但
__repr__
缺失时,
repr()
和交互式环境直接显示默认地址,不会尝试用
__str__
。 立即学习 “ Python免费学习笔记(深入) ”; 这意味着:只写
__str__
不够,
logging.debug(obj)
、pdb 调试、Jupyter 输出仍难读 建议始终实现
__repr__
,哪怕最简版:
f"{self.__class__.__name__}({id(self):x})"
别让
__repr__
返回空字符串或 None,那会导致
TypeError
真正容易被忽略的是:
__repr__
中对属性值的转义处理。比如
name = "Alice's cat"
,直接插进去会破坏字符串结构,得用
repr(self.name)
而不是
self.name
。

相关文章