Python中__str__和__repr__的区别

Python中__str__和__repr__的区别

技术背景

在Python中,__str____repr__ 是两个特殊的方法,它们都用于返回对象的字符串表示。然而,它们的设计目的和使用场景有所不同。理解这两个方法的区别,有助于我们更好地进行对象的调试、日志记录和用户交互。

实现步骤

1. 默认实现

在没有自定义 __str____repr__ 方法时,Python 提供的默认实现通常用处不大。例如:

1
2
3
4
5
class Sic(object):
pass

print(str(Sic()))
print(repr(Sic()))

输出结果可能类似:

1
2
<__main__.Sic object at 0x8b7d0>
<__main__.Sic object at 0x8b7d0>

默认实现仅显示对象所属的类和对象在内存中的地址。

2. 自定义 __repr__

__repr__ 的目标是提供对象的无歧义表示,通常用于调试和开发。我们应该尽量让 __repr__ 返回的字符串能够通过 eval 函数重新创建出相同的对象。例如:

1
2
3
4
5
6
7
8
9
10
11
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den

def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'


f = Fraction(1, 2)
print(repr(f))

输出结果:

1
Fraction (1,2)

3. 自定义 __str__

__str__ 的目标是提供对象的可读表示,通常用于用户交互。例如:

1
2
3
4
5
6
7
8
9
10
11
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den

def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'


f = Fraction(1, 2)
print(str(f))

输出结果:

1
(1/2)

核心代码

以下是一个完整的示例,展示了 __str____repr__ 的不同实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den

def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'

def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'


f = Fraction(1, 2)
print('使用 repr 表示对象:', repr(f))
print('使用 str 表示对象:', str(f))

最佳实践

  • 实现 __repr__:为每个自定义类实现 __repr__ 方法,确保开发人员在调试和日志记录时能够准确了解对象的状态。
  • 实现 __str__:如果需要为用户提供对象的可读表示,实现 __str__ 方法。例如,在生成报告或用户界面中显示对象信息时。
  • 使用 __repr__ 作为 __str__ 的后备:如果没有定义 __str__ 方法,Python 会使用 __repr__ 方法来代替。因此,__repr__ 应该是一个合理的默认选择。

常见问题

1. __repr__ 一定要能通过 eval 重建对象吗?

虽然 eval(repr(obj)) == obj 是一个理想的目标,但在实际应用中并不总是可行的。有些对象可能依赖于外部资源或复杂的初始化过程,无法简单地通过字符串表示重建。在这种情况下,__repr__ 应该提供足够的信息来描述对象的状态。

2. 为什么容器的 __str__ 使用元素的 __repr__ 而不是 __str__

这是为了避免字符串干扰容器的表示。例如,如果一个列表中的字符串元素使用 __str__ 表示,可能会导致列表的表示变得混乱。使用 __repr__ 可以确保元素的表示更加清晰和无歧义。

3. 如果只实现一个方法,应该选择哪个?

如果只能实现一个方法,建议选择 __repr__。因为 __repr__ 可以作为 __str__ 的后备,而且对于开发和调试非常有用。


Python中__str__和__repr__的区别
https://119291.xyz/posts/2025-04-21.difference-between-str-and-repr-in-python/
作者
ww
发布于
2025年4月22日
许可协议