来自 effbot 的 (非官方)Python 参考 Wiki(存档副本):
__str__
"计算对象的“非正式”字符串表示。这与 __repr__
不同,因为它不必是一个有效的 Python 表达式:相反,可能会使用更方便或更简洁的表示方法。"
说实话,eval(repr(obj))
从来没有被使用过。如果你发现自己在使用它,那么应该停止,因为eval
是危险的,而字符串是序列化对象的一种非常低效的方式(应该使用pickle
代替)。
因此,我建议将__repr__ = __str__
。原因是str(list)
调用元素的repr
(我认为这是Python的最大设计缺陷之一,Python 3没有解决)。实际的repr
可能不会对print([your, objects])
的输出有太多帮助。
要澄清这一点,根据我的经验,repr
函数最有用的用例是将一个字符串放入另一个字符串中(使用字符串格式化)。这样,你就不必担心引号转义或任何其他问题了。但请注意,这里没有发生eval
。
eval(repr(obj))
是一种测试和经验法则 - 如果它能够正确地重新创建原始对象,那么你就拥有了一个不错的__repr__
实现。这并不意味着你应该真的用这种方式序列化对象。 - jwgstr
- 从给定对象创建新的字符串对象。
repr
- 返回对象的规范字符串表示形式。
区别:
str():
repr():
class Foo:
def __repr__(self):
return "repr"
def __str__(self):
return "str"
foo = Foo()
foo # repr
print(foo) # str
__str__
方法可以通过调用str(obj)
在对象上调用,并应返回一个易于理解的字符串。
__repr__
方法可以通过调用repr(obj)
在对象上调用,并应返回内部对象(对象字段/属性)
以下示例可能有所帮助:
class C1:pass
class C2:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
class C3:
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
class C4:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
ci1 = C1()
ci2 = C2()
ci3 = C3()
ci4 = C4()
print(ci1) #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2) #C2 class str
print(str(ci2)) #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3) #C3 class repr
print(str(ci3)) #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4) #C4 class str
print(str(ci4)) #C4 class str
print(repr(ci4)) #C4 class repr
来自书籍《流畅的Python》:
一个Python对象的基本要求是提供可用的字符串表示形式,一种用于调试和日志记录,另一种用于呈现给最终用户。这就是为什么数据模型中存在特殊方法
__repr__
和__str__
。
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
decimal.Decimal(23) / decimal.Decimal("1.05")
的结果进行 print()
时,会输出原始数字;这个输出是以字符串形式呈现的,可以通过 __str__()
实现。如果我们只输入表达式,将得到一个 decimal.Decimal
输出 — 这个输出是以表示形式呈现的,可以通过 __repr__()
实现。所有 Python 对象都有两种输出形式。字符串形式旨在为人类可读。表示形式旨在产生输出,如果将其馈送给 Python 解释器,则(可能时)会重现所表示的对象。__str__
使用包含对象的__repr__
。>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
< p > Python更注重无歧义性而非易读性,一个tuple
的__str__
调用会调用包含对象的__repr__
,即对象的"正式"表示。虽然正式表示比非正式表示更难读,但它是无歧义的并且更能防止错误。
__str__
没有被定义时,它使用 __repr__
!所以,你是错误的。 - jiten
__repr__
并不要求返回一个有效的 Python 表达式。 - Mad Physicist