Python中无法获取__repr__()方法的实现

3

我正在阅读David Beazley和Brian K. Jones所著的著名Python书籍《Python Cookbook》。在他们的“类和对象”章节中,他们写了以下代码:

class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return 'Point({0.x!r}, {0.y!r})'.format(self)
    def __str__(self):
        return '({0.x!s}, {0.y!s})'.format(self)

现在,我只知道repr()方法用于向开发人员表示对象,而str()用于向盲人用户表示对象。但在这两种方法中,“return”之后正在发生什么?无疑,这两种情况下都有元组。但是这些元组具有什么样的成员?我以前没有见过这样的内容。


2
请仔细查看,这两个函数返回的是格式化后的字符串,而不是元组。 - Ofer Sadan
好的,没错,但整个东西是怎么运作的呢? - Saswata Mishra
只是返回一个字符串,仅此而已。 - Chris Doyle
是的,但那些 {0.x!r} 是什么意思呢?无法解码其含义。 - Saswata Mishra
2
@SaswataMishra 这份文档详细介绍了这个。 - a_guest
显示剩余2条评论
3个回答

2
您好,以下是您需要翻译的内容:

在您的示例中,__repr____str__都返回格式化字符串,而不是元组。当对象显式或隐式地调用repr()str()时,将调用这些函数。

例如,print(Point(1,2))会打印__str__的结果,因为它在内部调用str(),但是print([Point(1,2)])将打印__repr__的结果。

对于您自己的对象,这些方法可以返回任何字符串,只要它们是字符串即可。


1
这里是格式语法的具体细节解释。使用str.format方法,您可以填充给定字符串实例中形如{...}的占位符。它们按以下方式使用位置参数:
>>> '{}:{}'.format(1, 2)
'1:2'
>>> '{0}:{1}'.format(1, 2)
'1:2'
>>> '{1}:{0}'.format(1, 2)
'2:1'

这意味着您可以在花括号内指定位置参数的编号。字符串可以多次引用位置参数:

>>> '{0}:{1}:{0}'.format(1, 2)
'1:2:1'

使用.x符号可以让您访问该参数的属性。例如:
>>> class Test:
...     x = 1
...     y = 2
... 
>>> '{0.x}:{0.y}'.format(Test)
'1:2'

通过使用!r,您可以强制使用该对象的__repr__而不是__str__。例如:

>>> class Test:
...     def __str__(self):
...         return '__str__'
...     def __repr__(self):
...         return '__repr__'
... 
>>> '{0}'.format(Test())
'__str__'
>>> '{0!s}'.format(Test())
'__str__'
>>> '{0!r}'.format(Test())
'__repr__'

所以,结合所有这些信息,我们得到以下内容:
'Point({0.x!r}, {0.y!r})'.format(self)

这里定义了一个带有两个占位符的格式化字符串({0.x!r}{0.y!r})。它们应该用第一个位置参数的xy属性填充(请记住,{0}将被替换为第一个参数,所以{0.x}请求该参数的x属性)。最后,!r请求该对象的__repr__而不是默认的__str__

同样的推理也适用于__str__方法。

顺便说一下,格式化语法还允许关键字参数,并且可以通过其名称进行引用:

>>> '{first}:{second}'.format(first=1, second=2)
'1:2'
>>> '{second}:{first}'.format(first=1, second=2)
'2:1'

0
你可能想要在解释器中尝试一下,以了解正在发生的事情:
>>> class Point:
    def __init__(self, x, y):
        """Initialize self."""
        self.x, self.y = x, y
    def __repr__(self):
        """Return repr(self)."""
        return f'{type(self).__name__}({self.x!r}, {self.y!r})'
    def __str__(self):
        """Return str(self)."""
        return f'({self.x!s}, {self.y!s})'

>>> Point(1, 2) # causes implicit call to __repr__
Point(1, 2)
>>> print(_) # causes implicit call to __str__
(1, 2)
>>> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接