我正在尝试用自己的python学习python而且我坚持__repr__
函数。虽然我已经在__repr__
上阅读了很多关于python文档的帖子。所以我决定在这里提出这个问题。下面的代码解释了我的困惑。
class Point:
def __init__(self,x,y):
self.x, self.y = x,y
def __repr__(self):
return 'Point(x=%s, y=%s)'%(self.x, self.y)
def print_class(self):
return 'Point(x=%s, y=%s)'%(self.x, self.y)
p = Point(1,2)
print p
print p.print_class()
Point(x=1, y=2)
Point(x=1, y=2)
如果正常函数也可以执行类似的任务,那么__repr__
优于print_class()
(在我的情况下是正常函数)函数的额外优势是什么。
答案 0 :(得分:5)
__repr__
函数在内部由repr()
调用。直接打印对象时会调用repr()
,而类不会定义__str__()
。来自documentation -
<强>对象.__再版__(个体)强>
由repr()内置函数和字符串转换(反向引号)调用,以计算对象的“官方”字符串表示形式。如果可能的话,这应该看起来像一个有效的Python表达式,可用于重新创建具有相同值的对象(给定适当的环境)。如果这不可能,则形式为&lt; ...一些有用的描述的字符串...&gt;应该退还。返回值必须是字符串对象。如果一个类定义
__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
答案 1 :(得分:3)
不同之处在于,__repr__
函数在某些上下文中由Python自动调用,并且是具有特定要求的预定义API的一部分。例如,如果您在创建p
对象后在交互式shell中单独输入print p
(而不是p
),则会调用其__repr__
。如果您未在print p
上定义__str__
,它也将用于p
。 (也就是说,您必须编写print p.print_class()
,但您不必编写print p.__repr__()
; Python会自动为您调用__repr__
。)描述__repr__
的要求在the documentation中:
由repr()内置函数和字符串转换(反向引号)调用,以计算对象的“官方”字符串表示形式。如果可能的话,这应该看起来像一个有效的Python表达式,可用于重新创建具有相同值的对象(给定适当的环境)。如果这不可能,则形式为&lt; ...一些有用的描述的字符串...&gt;应该退还。
简而言之,如果您编写自己的方法print_class
,您可以让它做任何您想做的事情并告诉人们如何使用它,因为它是您的API。如果你使用__repr__
,你应该遵循Python API的约定。根据具体情况,任何一个都可能有意义。
答案 2 :(得分:0)
它可以帮助您进行更有效的编码工作。即使您使用'print_class()'等用户定义方法作为 repr 获得相同的结果,但您不需要通过 repr 输入'.print_class()'方法