Python的`str()`函数是否调用一个类的`__str__()`函数?

25 浏览
0 Comments

Python的`str()`函数是否调用一个类的`__str__()`函数?

如果我定义了一个具有自己的__str__()函数的类,那么对于我的类实例astr(a)是否等价于a.__str__()

我查过了Python文档,上面并没有明确说明这个情况。

admin 更改状态以发布 2023年5月23日
0
0 Comments

是的,确实如此。请看以下示例:

>>> class A:
...     def __init__(self, a):
...         self.a = a
...     def __str__(self):
...         print "Inside __str__"
...         return self.a
...
>>>
>>> a = A('obj1')
>>> a
<__main__.A instance at 0x0000000002605548>
>>>
>>> a.__str__()
Inside __str__
'obj1'
>>>
>>> str(a)
Inside __str__
'obj1'

而且,在__str__()文档中,我们有:

object.__str__(self)

str(object)和内置函数format()print()调用,
计算对象的“非正式”或可打印的字符串表示形式。 返回值必须是一个字符串对象。

0
0 Comments

简短回答:是的!


根据 Python 文档(我突出了相关部分):

object.__str__(self)

通过 str(object) 和内置函数 format() 和 print() 调用,计算对象的“非正式”或易于打印的字符串表示。返回值必须是字符串对象。

此方法与 object.__repr__() 的区别在于,没有期望__str__() 返回一个有效的 Python 表达式:可以使用更方便或简洁的表示。

由内置类型 object 定义的默认实现调用 object.__repr__()

因此,在执行 str(your_instance) 时,通常会调用 your_instance.__str__


详细回答:对于“特殊方法”(具有两个前导下划线和两个尾随下划线的方法),有一个例外,因为这些方法是在类上查找而不是在实例上查找。因此,str(a) 实际上是 type(a).__str__(a) 而不是 a.__str__()。但在大多数情况下,它们是相同的,因为很少在实例上覆盖类的方法。特别是不覆盖特殊方法。

还可以参见有关“特殊方法查找”的相关文档

对于自定义类,只有在对象类型上定义时,才能保证特殊方法的隐式调用能够正确地工作,而不是在对象的实例字典中定义。

所以像@zzh1996在评论里指出的那样,即使实例拥有自定义的可调用__str__属性,下面的代码仍将使用类上定义的方法:

>>> class A(object):
...     def __str__(self):
...         return 'a'
>>> instance = A()
>>> instance.__str__ = lambda: 'b'
>>> str(instance)
'a'
>>> instance.__str__()
'b'

0