Python中__str__和__repr_之间有什么区别?


当前回答

除非您特别采取行动以确保其他情况,否则大多数类对以下两种情况都没有帮助:

>>> class Sic(object): pass
... 
>>> print(str(Sic()))
<__main__.Sic object at 0x8b7d0>
>>> print(repr(Sic()))
<__main__.Sic object at 0x8b7d0>
>>> 

正如您所看到的,没有区别,也没有超出类和对象id的信息。如果您只覆盖这两个中的一个…:

>>> class Sic(object): 
...   def __repr__(self): return 'foo'
... 
>>> print(str(Sic()))
foo
>>> print(repr(Sic()))
foo
>>> class Sic(object):
...   def __str__(self): return 'foo'
... 
>>> print(str(Sic()))
foo
>>> print(repr(Sic()))
<__main__.Sic object at 0x2617f0>
>>> 

如您所见,如果重写__repr_,那么它也用于__str__,但反之亦然。

要知道的其他关键提示:内置容器上的__str__使用__repr_而不是__str__来表示它包含的项。而且,尽管在典型的文档中找到了关于这个主题的单词,但几乎没有人会将__repr_对象设置为eval可以用来构建相等对象的字符串(这太难了,而且不知道相关模块是如何实际导入的,这实际上是不可能的)。

因此,我的建议是:专注于使__str__合理地具有可读性,并尽可能地明确__repr___,即使这会干扰模糊的不可实现的目标,即使__repr_的返回值可接受作为__eval___的输入!

其他回答

>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

当对decimal.decimal(23)/decimal.Ddecimal(“1.05”)的结果调用print()时,将打印原始数字;此输出为字符串形式,可以使用__str__()实现。如果我们简单地输入表达式,我们会得到一个decimal.decimal输出-这个输出是以表示形式的,可以用__repr_()实现。所有Python对象都有两种输出形式。字符串形式设计为人类可读。表示形式被设计为生成输出,如果将其提供给Python解释器,将(在可能的情况下)再现所表示的对象。

str-从给定对象创建一个新的字符串对象。

repr-返回对象的规范字符串表示形式。

差异:

str():

使对象可读为最终用户生成输出

repr():

需要复制对象的代码为开发人员生成输出

(2020条目)

Q: __str__()和__repr___()之间有什么区别?

TL;博士:

LONG

这个问题已经存在了很长一段时间,有很多答案都是正确的(更不用说来自几个Python社区的传说[!])。然而,当谈到本质时,这个问题类似于询问str()和repr()内置函数之间的区别。我将用我自己的语言描述这些差异(这意味着我可能是在“借用”核心Python编程,所以请原谅我)。

str()和repr()都有相同的基本任务:它们的目标是返回Python对象的字符串表示。什么样的字符串表示是它们的区别。

str()和__str__()返回可打印的字符串表示形式对象。。。人类可读/供人类食用的东西repr()&__repr_()返回一个对象的字符串表示,该对象是一个有效的Python表达式,您可以传递给eval()或在Python shell中键入,而不会出现错误。

例如,让我们将一个字符串分配给x,将一个int分配给y,并简单地显示每个字符串的可读字符串版本:

>>> x, y = 'foo', 123
>>> str(x), str(y)
('foo', '123')

我们可以在这两种情况下获取引号中的内容并将其逐字输入Python解释器吗?让我们试一试:

>>> 123
123
>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

显然,您可以使用int,但不必使用str。同样,虽然我可以将“123”传递给eval(),但这对“foo”不起作用:

>>> eval('123')
123
>>> eval('foo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'foo' is not defined

所以这告诉你Python shell只是eval()是你给它的。明白了吗?现在,让我们repr()两个表达式,看看我们得到了什么。更具体地说,获取其输出并将其转储到解释器中(这一点我们将在后面讨论):

>>> repr(x), repr(y)
("'foo'", '123')
>>> 123
123
>>> 'foo'
'foo'

哇,他们都工作了?这是因为“foo”虽然是该字符串的可打印字符串表示,但它不是可求值的,但“'fo'”是.123是str()或repr()调用的有效Python int。当我们用这些调用eval()时会发生什么?

>>> eval('123')
123
>>> eval("'foo'")
'foo'

它之所以有效,是因为123和“foo”是有效的Python对象。另一个关键点是,虽然有时两者都返回相同的东西(相同的字符串表示),但情况并非总是如此。(是的,是的,我可以在eval()工作的地方创建一个变量foo,但这不是重点。)

关于这两对的更多事实

有时,str()和repr()是隐式调用的,这意味着它们是代表用户调用的:当用户执行print(Py1/Py2)或调用print()(Py3+)时,即使用户没有显式调用str((),也会在显示对象之前代表用户进行这样的调用。在Pythonshell(交互式解释器)中,如果在>>提示符下输入变量并按RETURN,解释器将显示对该对象隐式调用repr()的结果。要将str()和repr()连接到__str__()和__repr___(),请认识到对内置函数(即str(x)或repr(y))的调用会导致调用其对象的相应特殊方法:x.__str____通过为Python类实现__str__()和__repr_(),可以重载内置函数(str()和repr()),允许将类的实例传递给str(()和repr()。当进行此类调用时,它们会返回并调用类'__str__()和__repr___()(根据#3)。

Hans Petter Langtanch的《Python脚本用于计算科学》一书第358页明确指出

__repr_的目标是对象的完整字符串表示;__str__是返回一个用于打印的字符串。

所以,我更愿意把他们理解为

repr=再现str=字符串(表示)

从用户的角度来看尽管这是我在学习python时产生的误解。

同一页还提供了一个小但很好的示例,如下所示:

实例

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

基本上__str__或str()用于创建人类可读的输出,这些输出必须面向最终用户。另一方面,repr()或__repr_主要返回对象的规范字符串表示,用于调试和开发,帮助程序员。