__repr__
函数是被内部的
repr()
调用的。当你直接打印对象并且类没有定义
__str__()
时,会调用
repr()
。详见
documentation -
object.__repr__(self)
由 repr() 内置函数和字符串转换(反引号)调用,计算对象的“官方”字符串表示形式。如果可能的话,这应该看起来像一个有效的Python表达式,可以在适当的环境中使用它来重新创建具有相同值的对象。如果这不可能,应该返回形如<...some useful description...> 的字符串。返回值必须是字符串对象。如果一个类定义了 __repr__()
但没有定义 __str__()
,那么在需要实例的“非正式”字符串表示时也会使用 __repr__()
。
在您的情况下,对于
print_class()
,您必须在打印对象时明确调用该方法。但是,在
__repr__()
的情况下,它会被
print
内部调用。
当您混合不同的类/类型时,这特别有用。例如,让我们考虑一个可以包含数字和您的
point
类对象的列表,现在您想要打印列表的元素。
如果您没有定义
__repr__()
或
__str__()
,则必须首先检查实例是否属于类型
Point
,如果是,则调用
print_class()
,否则直接打印数字。
但是,当您的类定义了
__repr__()
或
__str__()
时,您可以直接调用列表的所有元素上的
print
,
print
语句会在内部处理正确的值。
例如,假设有一个具有
print_class()
方法但没有
__repr__()
或
__str__()
的类,代码-
>>> class CA:
... def __init__(self,x):
... self.x = x
... def print_class(self):
... return self.x
...
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
... print(i)
...
1
2
3
<__main__.CA object at 0x00590F10>
<__main__.CA object at 0x005A5070>
SyntaxError: invalid syntax
>>> for i in l:
... if isinstance(i, CA):
... print(i.print_class())
... else:
... print(i)
...
1
2
3
4
5
如您所见,当我们在列表中混合数字和类型为
CA
的对象时,当我们只执行
print(i)
时,它没有打印出我们想要的内容。为了使其正常工作,我们必须检查
i
的类型并调用适当的方法(如第二个例子中所做)。
现在假设有一个实现
__repr__()
而不是
print_class()
的类 -
>>> class CA:
... def __init__(self,x):
... self.x = x
... def __repr__(self):
... return str(self.x)
...
>>>
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
... print(i)
...
1
2
3
4
5
正如您在第二个案例中所看到的,简单地打印输出起作用了,因为
print
内部首先调用
__str__()
,而由于它不存在,就回退到
__repr__()
。
不仅如此,当我们执行
str(list)
时,内部会调用每个列表元素的
__repr__()
。例如:
第一种情况(没有
__repr__()
)-
>>> str(l)
'[1, 2, 3, <__main__.CA object at 0x005AB3D0>, <__main__.CA object at 0x005AB410>]'
第二种情况(使用__repr__()
) -
>>> str(l)
'[1, 2, 3, 4, 5]'
此外,在交互式解释器中,当您直接使用对象时,它会显示
repr()
函数的输出,例如 -
>>> class CA:
... def __repr__(self):
... return "CA instance"
...
>>>
>>> c = CA()
>>> c
CA instance