__str__
和__repr__
都是Python中基于对象状态返回字符串的特殊方法
在需要打印一个对象,或将其传递给format、str.format
或str
的时候,如果定义了__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 datetime
Code 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.977951
Code language: CSS (css)
重新创建我们丢失的对象是一件简单的事情:
>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180
Code 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 s
Code 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__