Python 中 __str__ 和 __repr__ 有什么区别?

Python 中 __str__ 和 __repr__ 有什么区别

__str____repr__都是Python中基于对象状态返回字符串的特殊方法

在需要打印一个对象,或将其传递给format、str.formatstr的时候,如果定义了__str__方法,则将调用该方法,否则将使用__repr__方法。
__repr__方法由内置函数repr调用,当它执行返回对象的表达式时,它会在 python shell 上回显。
如果只能实现一个,请实现__repr__

repr的默认实现

默认对象的repr实现请参考:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      type(self).__module__, type(self).__qualname__, hex(id(self)))Code language: PHP (php)

主要打印对象的模块、类名以及其在内存中位置的十六进制表示:

<__main__.Foo object at 0x7f80665abdd0>Code language: HTML, XML (xml)

这些信息不是很有用,但没有办法推导出如何准确地创建任何给定实例的规范表示,总比没有好,至少告诉我们如何在内存中唯一地识别它。

怎样使repr更有用?

以datetime为例来说明下。
使用 Python shell 和datetime对象。首先我们需要导入datetime模块:

import datetimeCode language: JavaScript (javascript)
  • 如果在 shell 中调用datetime.now,将看到重新创建等效日期时间对象所需的一切。这是由 datetime__repr__输出的:
>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)Code language: CSS (css)
  • 如果打印一个日期时间对象,会看到一种可读性很好的时间格式。这是由 datetime 的__str__实现的:
>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951Code language: CSS (css)

重新创建我们丢失的对象是一件简单的事情:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180Code language: PHP (php)

如何实现它们?

在开发过程中,大家都希望能够以相同的状态重现对象。下面是 datetime 对象的__repr__(Python 源代码)定义方式。它相当复杂,因为需要复制这样一个对象所需的所有属性:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return sCode language: PHP (php)

如果希望对象具有更易读的表示,可以实现__str__。以下是 datetime 对象(Python 源代码)的__str__实现方式:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')Code language: PHP (php)

结论

为对象定义__repr__,以便和其他开发人员在开发时使用它时有一个可重现的示例。如果对象需要展示可读性好的字符串,则需要实现__str__

发表评论