__str__和__repr__的作用是什么?

93 投票
8 回答
96586 浏览
提问于 2025-04-16 04:00

我真的不太明白在Python中__str____repr__是用来干嘛的。我知道__str__是用来返回一个对象的字符串表示的。但是我为什么需要这个呢?在什么情况下会用到?另外,我也读过关于__repr__的用法。

但我不明白的是,我到底在哪些地方会用到它们呢?

8 个回答

18

在之前的回答基础上,我再给大家举几个例子。如果用得当,strrepr之间的区别是很明显的。简单来说,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是个好主意。

69

你会发现这两个东西在交互式会话中用得特别多。如果你打印一个对象,它会调用这个对象的 __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__ 返回相同的值也是很常见的,尤其是在内置类型中。

90

__repr__

这个方法是通过内置的 repr() 函数和字符串转换(反引号)来调用的,用来计算一个对象的“官方”字符串表示。如果可能的话,这个字符串应该看起来像一个有效的 Python 表达式,能够在合适的环境下重建出相同值的对象。

__str__

这个方法是通过内置的 str() 函数和打印语句来调用的,用来计算一个对象的“非正式”字符串表示。

如果你有一个类,并且希望在将这个对象作为字符串的一部分时,输出一些有用或非正式的信息,就使用 __str__。例如,你可以为 Django 模型定义 __str__ 方法,这样在 Django 管理界面中就会显示出来。这样你看到的就不是像 <Model object> 这样的内容,而是一个人的名字和姓氏,或者一个事件的名称和日期等等。


__repr____str__ 是相似的,实际上有时候它们是相等的(这是来自标准库中 sets.pyBaseSet 类的例子):

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__

撰写回答