【问题标题】:Can't getting the implementation of __repr__() method in python无法在 python 中实现 __repr__() 方法
【发布时间】:2020-02-20 04:16:16
【问题描述】:

我正在阅读 David Beazley 和 Brian K. Jones 的名为“python cookbook”的著名 Python 书籍。在他们的“类和对象”一章中,他们编写了以下代码:

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() 用于向盲人用户表示。但是在这两种方法中,“返回”之后发生了什么?在这两种情况下肯定都有元组。但是元组有什么样的成员?我以前从未见过这样的事情。

【问题讨论】:

  • 仔细看,两个函数都返回格式化字符串,而不是元组
  • 好吧,但是整个过程怎么样?
  • 它只是返回一个字符串。就这些
  • 是的,但那些 {0.x!r} 是什么?无法解读含义。
  • @SaswataMishra The docs 详细介绍了这一点。

标签: python python-3.x class methods tuples


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    以下是具体formatting syntax 的细分。使用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'
    

    【讨论】:

      【解决方案3】:

      您可能想在解释器中尝试一下,看看发生了什么:

      >>> 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)
      >>> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-06
        • 2015-07-29
        • 1970-01-01
        • 2012-06-14
        • 2020-10-04
        • 2019-03-24
        • 2010-12-31
        • 2021-09-11
        相关资源
        最近更新 更多