Python __repr__的目的


139
def __repr__(self):
  return '<%s %s (%s:%s) %s>' % (
    self.__class__.__name__, self.urlconf_name, self.app_name,
    self.namespace, self.regex.pattern)

此方法的意义/目的是什么?


@ zjm1126:您想知道为什么>>> variable打印__repr__()返回的内容吗?
EstebanKüber'09

18
该文档使人们入睡。另外,向他人学习如何使用它很有帮助。
Concerned_Citizen


2
对于正在学习Python的Java开发人员,最好的查看方式是Java中的toString()。
拉维

Answers:


188

__repr__应该返回对象的可打印表示形式,这很可能是创建该对象的一种可能方式。请参阅此处的官方文档。__repr__对于开发人员而言更多,而__str__对于最终用户而言则更多。

一个简单的例子:

>>> 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)
>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)

2
lazy1:我主要是想修复格式(使示例尽可能与示例会话中看到的匹配非常有用),但是我还调整了输出格式,使其明显不同于赋值,因为对于对此感到困惑的人,imho大大提高了清晰度。(如果我走得太远,只需重新编辑,我欠你一杯啤酒。)


1
这也许应该用%R来代替%S:stackoverflow.com/questions/6005159/...
乔纳森·阿德尔森

43
这不是真的正确。__str__是应该是人类可读的输出:__repr__应该是Python解释器可读的表示形式(即,将字符串提供给解释器应重新创建对象)。__str__但是,如果对象没有方法,__repr__则使用该方法。还如所指出的:该实施例中实际打印__str__的方法self.xself.y%r应,而不是使用%s在字符串格式化操作(因为类没有定义__str____repr__实际上是反正返回,但它是一个异常)。
Daniel Andersson

20

Python文档中对此进行了很好的解释:

reprobject):返回一个字符串,其中包含对象的可打印表示形式。这与转换(反引号)产生的值相同。能够以普通功能访问此操作有时很有用。对于许多类型,此函数会尝试返回一个字符串,该字符串将在传递给时产生一个具有相同值的对象eval(),否则表示形式是一个用尖括号括起来的字符串,其中包含对象类型的名称以及其他信息通常包括对象的名称和地址。类可以通过定义__repr__()方法来控制此函数为其实例返回的内容。

因此,您在这里看到的是的默认实现__repr__,这对于序列化和调试很有用。


5
我认为不赞成使用获取对象“表示形式”的反引号(或“反引号”)方法,并已从版本3.0
MatrixFrog

MatrixFrog:都正确,但是当前的2.x文档仍然说明了这一点,这是引用的来源。

对于许多对象,__repr__和__str__是相同的功能。实际上,如果仅定义__str__,则__repr__默认情况下仅调用__str__。不正确的最明显情况是字符串本身:str('stackoverflow')返回,stackoverflow而repr('stackoverflow')是'stackoverflow'
09年

6
倒退,__ repr__从不使用__str__,但是相反的情况可能会发生。参见docs.python.org/reference/…–

13

__repr__由独立的Python解释器用来显示可打印格式的类。例:

~> python3.5
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class StackOverflowDemo:
...     def __init__(self):
...         pass
...     def __repr__(self):
...         return '<StackOverflow demo object __repr__>'
... 
>>> demo = StackOverflowDemo()
>>> demo
<StackOverflow demo object __repr__>

如果__str__在类中未定义方法,则它将调用该__repr__函数以尝试创建可打印的表示形式。

>>> str(demo)
'<StackOverflow demo object __repr__>'

此外,默认情况下print(),该类将被调用__str__


文档,如果需要的话



1

查看它们之间差异的示例(我从此复制),

>>> x=4
>>> repr(x)
'4'
>>> str(x)
'4'
>>> y='stringy'
>>> repr(y)
"'stringy'"
>>> str(y)
'stringy'

的回报repr()str()是相同的int x,但有一个为返回值之间的差异str y-一个是正式的,另一个是非正式的。形式表示和非正式表示之间最重要的区别之一是,__repr__str值的默认实现可以称为eval的参数,而返回值将是有效的字符串对象,如下所示:

>>> repr(y)
"'a string'"
>>> y2=eval(repr(y))
>>> y==y2
True

如果您尝试将返回值__str__作为eval的参数调用,则结果将无效。


1

当我们通过定义类来创建新类型时,我们可以利用Python的某些功能使新类易于使用。这些功能之一是“特殊方法”,也称为“魔术方法”。

特殊方法的名称以两个下划线开头和结尾。我们定义它们,但通常不直接按名称调用它们。而是在特定情况下自动执行。

能够通过使用print语句输出对象实例的值很方便。当我们这样做时,我们希望该值以某种可以理解的明确格式表示在输出中。该再版特殊方法可用于安排要做到这一点。如果定义此方法,则在打印为其定义了该方法的类的实例的值时可以自动调用它。但是,应该提到的是,还有一个str特殊方法,用于相似但不相同的目的,如果我们也定义了它,则该方法可以优先。

如果尚未定义,则为Point3D类的repr方法,并将my_point实例化为Point3D的实例,然后执行此操作...

打印my_point ...我们可能会将其视为输出...

不是很好,是吗?

因此,我们定义了reprstr特殊方法,或同时定义了两者,以获得更好的输出。

**class Point3D(object):
    def __init__(self,a,b,c):
        self.x = a
        self.y = b
        self.z = c
    def __repr__(self):
        return "Point3D(%d, %d, %d)" % (self.x, self.y, self.z)
    def __str__(self):
        return "(%d, %d, %d)" % (self.x, self.y, self.z)
my_point = Point3D(1, 2, 3)
print my_point # __repr__ gets called automatically
print my_point # __str__ gets called automatically**

输出...

(1,2,3)(1,2,3)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.