Python中__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)。

其他回答

简而言之:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

简而言之,__repr_的目标是明确,__str__是可读。

这里有一个很好的例子:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

阅读本文档以了解代表:

repr(对象)返回包含对象的可打印表示形式的字符串。这与转换产生的值相同(相反引号)。有时,作为一个普通的函数。对于许多类型,此函数会尝试返回一个字符串,当传递给eval(),否则表示形式是一个字符串包含对象类型名称的尖括号以及通常包括姓名和对象的地址。类可以控制此函数返回的内容为其实例定义__repr_()方法。

以下是str的文档:

str(对象=“”)返回一个字符串,该字符串包含可打印的对象的表示。对于字符串,这将返回字符串它本身与repr(object)的区别在于str(object)没有始终尝试返回eval()可接受的字符串;它的目标是返回一个可打印的字符串。如果未给定参数,则返回空字符串“”。

__repr_:python对象的表示通常eval会将其转换回该对象

__str__:是你认为的文本形式的对象

e.g.

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

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

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

差异:

str():

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

repr():

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

除了给出的所有答案外,我想补充几点:-

1) 当您只需在交互式python控制台上写入对象名称并按enter键时,就会调用__repr_()。

2) __str__()在使用带有print语句的对象时被调用。

3) 在这种情况下,如果缺少__str__,那么print和任何使用str()的函数都会调用对象的__repr_()。

4) 容器的__str__(),当调用时将执行其包含元素的__repr_()方法。

5) 在__str__()内调用的str()可能会在没有基本情况的情况下递归,并且在最大递归深度上出错。

6) __repr_()可以调用repr(),它将尝试自动避免无限递归,用…替换已经表示的对象。。。。