__str__和__repr__的作用是什么?
我真的不太明白在Python中__str__
和__repr__
是用来干嘛的。我知道__str__
是用来返回一个对象的字符串表示的。但是我为什么需要这个呢?在什么情况下会用到?另外,我也读过关于__repr__
的用法。
但我不明白的是,我到底在哪些地方会用到它们呢?
8 个回答
在之前的回答基础上,我再给大家举几个例子。如果用得当,str
和repr
之间的区别是很明显的。简单来说,repr
应该返回一个字符串,这个字符串可以直接复制粘贴来重建对象的确切状态,而str
则更适合用来记录日志和观察调试结果。下面是一些例子,展示了在一些常用库中的不同输出。
日期时间
print repr(datetime.now()) #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now()) #2017-12-12 18:49:27.134452
str
适合打印到日志文件中,而repr
则可以重新利用,如果你想直接运行它或者把它作为命令写入文件。
x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
Numpy
print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5])) #[1 2 3 4 5]
在Numpy中,repr
同样可以直接使用。
自定义的Vector3示例
class Vector3(object):
def __init__(self, args):
self.x = args[0]
self.y = args[1]
self.z = args[2]
def __str__(self):
return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)
def __repr__(self):
return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)
在这个例子中,repr
返回的字符串可以直接使用或执行,而str
则更适合用作调试输出。
v = Vector3([1,2,3])
print str(v) #x: 1, y: 2, z: 3
print repr(v) #Vector3([1,2,3])
需要记住的一点是,如果没有定义
str
但定义了repr
,那么str
会自动调用repr
。所以,至少定义repr
是个好主意。
你会发现这两个东西在交互式会话中用得特别多。如果你打印一个对象,它会调用这个对象的 __str__
方法;而如果你单独使用这个对象,它就会显示 __repr__
的内容:
>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25 <---- this is from __str__
>>> a
Decimal('1.25') <---- this is from __repr__
__str__
的目的是让人看起来尽量简单易懂,而 __repr__
则是希望能提供一些信息,让你可以用它来重新创建这个对象,虽然通常它显示的内容和最初创建时不完全一样,就像这个例子一样。
其实 __str__
和 __repr__
返回相同的值也是很常见的,尤其是在内置类型中。
这个方法是通过内置的
repr()
函数和字符串转换(反引号)来调用的,用来计算一个对象的“官方”字符串表示。如果可能的话,这个字符串应该看起来像一个有效的 Python 表达式,能够在合适的环境下重建出相同值的对象。
这个方法是通过内置的
str()
函数和打印语句来调用的,用来计算一个对象的“非正式”字符串表示。
如果你有一个类,并且希望在将这个对象作为字符串的一部分时,输出一些有用或非正式的信息,就使用 __str__
。例如,你可以为 Django 模型定义 __str__
方法,这样在 Django 管理界面中就会显示出来。这样你看到的就不是像 <Model object>
这样的内容,而是一个人的名字和姓氏,或者一个事件的名称和日期等等。
__repr__
和 __str__
是相似的,实际上有时候它们是相等的(这是来自标准库中 sets.py
的 BaseSet
类的例子):
def __repr__(self):
"""Return string representation of a set.
This looks like 'Set([<list of elements>])'.
"""
return self._repr()
# __str__ is the same as __repr__
__str__ = __repr__