`__repr__` 函数相对于普通函数的意义是什么 [英] what is the significance of `__repr__` function over normal function
问题描述
我正在尝试用自己的方式学习 Python,但我一直坚持使用 __repr__
函数.虽然我已经阅读了很多关于 __repr__
的帖子以及 python 文档.所以我决定在这里问这个问题.下面的代码解释了我的困惑.
class 要点:def __init__(self,x,y):self.x, self.y = x,ydef __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 = 点(1,2)打印打印 p.print_class()点(x=1,y=2)点(x=1,y=2)
如果一个普通函数也可以执行类似的任务,那么 __repr__
相对于 print_class()
(在我的例子中是一个普通函数)函数的额外优势是什么?
__repr__
函数由 repr()
内部调用.repr()
在直接打印对象时被调用,并且该类没有定义 __str__()
.来自 文档 -
object.__repr__(self)
由 repr() 内置函数和字符串转换(反引号)调用以计算对象的官方"字符串表示.如果可能的话,这应该看起来像一个有效的 Python 表达式,可用于重新创建具有相同值的对象(给定适当的环境).如果这是不可能的,则应返回形式为 <...一些有用的描述...> 的字符串.返回值必须是字符串对象.如果一个类定义了 __repr__()
但没有定义 __str__()
,那么 __repr__()
也用于实例的非正式"字符串表示需要那个班级的.
对于 print_class()
,您必须在打印对象时专门调用该方法.但是在 __repr__()
的情况下,它会被 print
内部调用.
当您混合不同的类/类型时,这尤其有用.例如,让我们使用一个列表,它可以包含 point
类的数字和对象,现在您要打印列表的元素.
如果你没有定义 __repr__()
或 __str__()
,你必须首先检查实例,它的类型是否为 Point
code> 如果是这样调用 print_class()
,或者如果不是直接打印数字.
但是当您的类定义了 __repr__()
或 __str__()
时,您可以直接在所有元素上调用 print
list,print
语句会在内部处理打印正确的值.
示例,让我们假设一个类具有 print_class()
方法,但没有 __repr__()
或 __str__()
,代码 -
如您所见,当我们在列表中混合数字和 CA
类型的对象时,然后当我们只执行 print(i)
时,它没有打印我们想要什么.为了使其正常工作,我们必须检查 i
的类型并调用适当的方法(如第二种情况中所做的那样).
现在让我们假设一个类实现了 __repr__()
而不是 print_class()
-
正如你在第二种情况下看到的,简单的打印工作,因为 print
在内部首先调用 __str__()
,并且因为它不存在回退到 __repr__()
.
不仅如此,当我们执行 str(list)
时,内部每个列表元素的 __repr__()
都会被调用.示例 -
第一种情况(没有 __repr__()
)-
第二种情况(使用 __repr__()
)-
<小时>
此外,在交互式解释器中,当您直接使用对象时,它会显示repr()
函数的输出,示例 -
I am trying to learn python with my own and i stucked at __repr__
function. Though i have read lots of post on __repr__
along with the python document. so i have decided to ask this Question here. The code bellow explains my confusion.
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)
If a normal function can also perform similar task then what is the extra advantage of __repr__
over print_class()
(in my case a normal function) function.
The __repr__
function is called by repr()
internally. repr()
is called when you are printing the object directly , and the class does not define a __str__()
. From documentation -
object.__repr__(self)
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the "official" string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines
__repr__()
but not__str__()
, then__repr__()
is also used when an "informal" string representation of instances of that class is required.
In your case for print_class()
, you have to specifically call the method when printing the object. But in case of __repr__()
, it gets internally called by print
.
This is especially useful, when you are mixing different classes/types . For Example lets take a list which can have numbers and objects of your point
class, now you want to print the elements of the list.
If you do not define the __repr__()
or __str__()
, you would have to first check the instance , whether its of type Point
if so call print_class()
, or if not directly print the number.
But when your class defines the __repr__()
or __str__()
, you can just directly call print
on all the elements of the list, print
statement would internally take care of printing the correct values.
Example , Lets assume a class which has print_class()
method, but no __repr__()
or __str__()
, code -
>>> 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
As you can see, when we mix numbers and objects of type CA
in the list, and then when we just did print(i)
, it did not print what we wanted. For this to work correctly, we had to check the type of i
and call the appropriate method (as done in second case).
Now lets assume a class that implements __repr__()
instead of 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
As you can see in second case, simply printing worked, since print
internally calls __str__()
first, and as that did not exist fell back to __repr__()
.
And not just this, when we do str(list)
, internally each list's element's __repr__()
is called. Example -
First case (without __repr__()
) -
>>> str(l)
'[1, 2, 3, <__main__.CA object at 0x005AB3D0>, <__main__.CA object at 0x005AB410>]'
Second case (with __repr__()
) -
>>> str(l)
'[1, 2, 3, 4, 5]'
Also, in interactive interpreter, when you are directly using the object, it shows you the output of repr()
function, Example -
>>> class CA:
... def __repr__(self):
... return "CA instance"
...
>>>
>>> c = CA()
>>> c
CA instance
这篇关于`__repr__` 函数相对于普通函数的意义是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!