Python对象.__ repr __(self)应该是一个表达式?

时间:2009-01-16 22:37:18

标签: python

我正在查看Python documentation中的内置对象方法,我对object.__repr__(self)的文档感兴趣。这就是它所说的:

  

由repr()内置函数调用   并通过字符串转换(反向   引用)计算“官方”   对象的字符串表示。如果   在所有可能的情况下,这应该是这样的   一个有效的Python表达式   用于重建一个对象   相同的价值(给定一个适当的   环境)。如果这不可能,   一个形式的字符串< ...一些有用的   描述...>应该退还。   返回值必须是字符串   宾语。如果一个类定义 repr ()   但不是 str (),那么 repr ()就是   也用于“非正式”字符串   表示实例   上课是必需的。

     

这通常用于调试,   所以重要的是   代表性是信息丰富的   明确的

对我来说最有趣的部分是......

  

如果可能,这应该看起来像一个有效的Python表达式,可用于重新创建具有相同值的对象

...但我不确定这意味着什么。它说它应该看起来就像一个可以用来重新创建对象的表达式,但这是否意味着它应该只是你可以使用的表达式的一个例子,或者它应该是一个实际的表达式,可以执行(eval等..)来重新创建对象?或者......它应该仅仅是为了纯粹的信息目的而重新使用实际表达式吗?

总的来说,我对我应该放在什么地方感到有点困惑。

7 个答案:

答案 0 :(得分:64)

>>> from datetime import date
>>>
>>> repr(date.today())        # calls date.today().__repr__()
'datetime.date(2009, 1, 16)'
>>> eval(_)                   # _ is the output of the last command
datetime.date(2009, 1, 16)

输出是一个字符串,可以由python解释器解析并产生相同的对象。

如果不可能,它应该以{{1​​}}。

的形式返回一个字符串

答案 1 :(得分:31)

它应该是一个Python表达式,当eval'd时,创建一个具有与此完全相同的属性的对象。例如,如果您的Fraction类包含两个整数,分子和分母,则__repr__()方法将如下所示:

# in the definition of Fraction class
def __repr__(self):
    return "Fraction(%d, %d)" % (self.numerator, self.denominator)

假设构造函数采用这两个值。

答案 2 :(得分:11)

指南:如果您可以简洁地提供精确表示将其格式化为Python表达式(这意味着它可以同时为eval '并在正确的上下文中直接复制到源代码中)。如果提供不精确的表示使用<...>格式

任何值都有许多可能的表示形式,但Python程序员最感兴趣的是一个重新创建值的表达式。请记住,了解Python的人是目标受众 - 这也是不精确表示应该包含相关上下文的原因。即使是默认的<XXX object at 0xNNN>,虽然几乎完全无用,但仍然提供类型id()(以区分不同的对象),并指示没有更好的表示可用。

答案 3 :(得分:4)

“但这是否意味着它应该只是一个你可以使用的表达式的例子,或者它应该是一个实际的表达式,可以执行(eval等...)来重新创建对象?或者...为了纯粹的信息目的,它应该只是重新使用的实际表达式吗?“

哇,这很麻烦。

  1. “可以使用的表达式的一个示例”不是特定对象的表示。这不是有用或有意义的。

  2. “实际表达式,可以......重新创建对象”和“重新创建用于创建对象的实际表达式”之间有什么区别?两者都是创建对象的表达式。这些之间没有实际的区别。 repr调用可以生成新表达式或原始表达式。在许多情况下,它们是相同的。

  3. 请注意,这并不总是可行的,实用的或可取的。

    在某些情况下,您会注意到repr()提供的字符串显然不是任何类型的表达式。您定义的任何类的默认repr()都不能用作表达式。

    在某些情况下,您可能在对象之间具有相互(或循环)引用。纠结的层次结构的repr()是没有意义的。

    在许多情况下,通过解析器逐步构建对象。例如,从XML或JSON或其他东西。那个代表是什么?原始的XML或JSON?显然不是,因为它们不是Python。它可能是一些生成XML的Python表达式。但是,对于一个巨大的XML文档,可能无法编写一个与解析XML相同功能的Python表达式。

答案 4 :(得分:1)

要查看repr在类中的工作方式,请先运行以下代码,然后使用 repr 方法。

class Coordinate (object):
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def getX(self):
        # Getter method for a Coordinate object's x coordinate.
        # Getter methods are better practice than just accessing an attribute directly
        return self.x
    def getY(self):

        # Getter method for a Coordinate object's y coordinate
        return self.y

    def __repr__(self):  #remove this and the next line and re-run
        return 'Coordinate(' + str(self.getX()) + ',' + str(self.getY()) + ')' 

>>>c = Coordinate(2,-8)
>>>print(c)

答案 5 :(得分:1)

'repr'表示代表。 首先,我们创建一个类坐标的实例。

x = Coordinate(3, 4) 

然后,如果我们在控制台中输入x,则输出为

<__main__.Coordinate at 0x7fcd40ab27b8>

如果您使用repr():

>>> repr(x)
Coordinate(3, 4)

输出与'Coordinate(3,4)'相同,只是它是一个字符串。您可以使用它来重新创建一个坐标实例。

最后,repr()肉类被打印出一个字符串,它是对象的表示形式。

答案 6 :(得分:0)

我认为这里的困惑源于英语。我的意思是__repr__();我所猜测的价值的“代表性”的缩写,就像@ S.Lott所说的

  

“实际表达式之间有什么区别,可以......重新创建对象”和“重新创建用于创建对象的实际表达式”?两者都是创建对象的表达式这些之间没有实际的区别。重新调用可以产生新的表达式或原始表达式。在许多情况下,它们是相同的。“

但在某些情况下,他们可能会有所不同。例如;坐标点,您可能希望c.coordinate返回:3,5c.__repr__返回Coordinate(3, 5)。希望更有意义......