__str__
Python和Python有什么区别__repr__
?
25 回答
亚历克斯总结得很好,但令人惊讶的是,它过于简洁。
首先,让我重申亚历克斯帖子中的要点:
- 默认实现是无用的(很难想到一个不会,但是是的)
__repr__
目标是明确的__str__
目标是可读的- 容器的
__str__
使用包含的对象'__repr__
默认实现没用
这主要是一个惊喜,因为 Python 的默认值往往相当有用。但是,在这种情况下,具有默认值的__repr__
行为如下:
return "%s(%r)" % (self.__class__, self.__dict__)
会太危险(例如,如果对象相互引用,太容易陷入无限递归)。所以 Python 出局了。请注意,有一个默认值为 true:如果__repr__
已定义,__str__
则该对象的行为就像__str__=__repr__
.
简单来说,这意味着:几乎您实现的每个对象都应该具有__repr__
可用于理解该对象的函数。实施__str__
是可选的:如果您需要“漂亮的打印”功能(例如,由报告生成器使用),请执行此操作。
的目标__repr__
是明确的
让我直接说出来——我不相信调试器。我真的不知道如何使用任何调试器,也从未认真使用过。此外,我认为调试器的最大故障在于它们的基本性质——我调试的大多数故障都发生在很久很久以前,在一个遥远的星系中。这意味着我确实怀着宗教热情相信伐木。日志记录是任何体面的即发即弃服务器系统的命脉。Python 使记录变得容易:可能使用一些特定于项目的包装器,您所需要的只是一个
log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)
但是你必须做最后一步——确保你实现的每个对象都有一个有用的 repr,这样这样的代码才能正常工作。这就是为什么会出现“评估”的事情:如果你有足够的信息eval(repr(c))==c
,那就意味着你知道所有要知道的事情c
。如果这很容易,至少以一种模糊的方式,那就去做吧。如果没有,请确保您有足够的信息c
。我通常使用类似 eval 的格式:"MyClass(this=%r,that=%r)" % (self.this,self.that)
. 这并不意味着您可以实际构造 MyClass,或者这些是正确的构造函数参数 - 但它是一种有用的形式来表达“这是您需要了解的有关此实例的所有信息”。
注意:我在%r
上面使用过,而不是%s
. 您总是想在实现中使用repr()
[或%r
等效的格式化字符] __repr__
,或者您正在破坏 repr 的目标。您希望能够区分MyClass(3)
和MyClass("3")
。
的目标__str__
是可读的
具体来说,它并非旨在明确 — 请注意str(3)==str("3")
. 同样,如果你实现一个 IP 抽象,让它的 str 看起来像 192.168.1.1 就可以了。在实现日期/时间抽象时,str 可以是“2010/4/12 15:35:22”等。目标是以用户而不是程序员想要阅读的方式表示它。砍掉无用的数字,假装是其他类——只要它支持可读性,它就是一种改进。
容器的__str__
使用包含的对象'__repr__
这似乎令人惊讶,不是吗?有点,但是如果它使用它们的可读性如何__str__
?
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
不是特别的。具体来说,容器中的字符串会很容易干扰其字符串表示。面对歧义,请记住,Python 抵制猜测的诱惑。如果您在打印列表时想要上述行为,只需
print("[" + ", ".join(l) + "]")
(您可能还可以弄清楚如何处理字典。
概括
为您实现__repr__
的任何类实现。这应该是第二天性。__str__
如果您认为有一个在可读性方面出错的字符串版本会很有用,请实施。
我的经验法则: __repr__
面向开发人员,__str__
面向客户。
除非您特别采取行动以确保其他情况,否则大多数课程对以下任何一项都没有有用的结果:
>>> 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__
!
__repr__
: python 对象的表示通常 eval 会将其转换回该对象
__str__
: 是你认为的文本形式的对象吗
例如
>>> 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
简而言之,目标
__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:
repr(object)
返回包含对象的可打印表示的字符串。这与转换(反向引号)产生的值相同。有时能够将此操作作为普通函数访问是很有用的。对于许多类型,此函数会尝试返回一个字符串,该字符串在传递给 时会产生具有相同值的对象
eval()
,否则表示是用尖括号括起来的字符串,其中包含对象类型的名称以及其他信息通常包括对象的名称和地址。类可以通过定义方法来控制此函数为其实例返回的内容__repr__()
。
这是 str 的文档:
str(object='')
返回一个字符串,其中包含一个对象的可很好打印的表示。对于字符串,这将返回字符串本身。不同之
repr(object)
处在于str(object)
它并不总是试图返回一个可以接受的字符串eval()
;它的目标是返回一个可打印的字符串。如果没有给出参数,则返回空字符串''
.
__str__
Python和Python有什么区别__repr__
?
__str__
(读作“dunder(双下划线)字符串”)和__repr__
(读作“dunder-repper”(表示“表示”))都是基于对象状态返回字符串的特殊方法。
__repr__
__str__
如果丢失,则提供备份行为。
因此,应该首先编写一个__repr__
允许您从它返回的字符串重新实例化等效对象的方法,例如使用eval
或通过在 Python shell 中逐个字符地键入它。
在以后的任何时候__str__
,当人们认为有必要时,可以为实例的用户可读字符串表示形式编写一个。
__str__
如果您打印一个对象,或将其传递给format
、str.format
或str
,则如果__str__
定义了一个方法,则将调用该方法,否则__repr__
将使用该方法。
__repr__
该__repr__
方法由内置函数调用,repr
当它评估返回对象的表达式时,它会在您的 python shell 上回显。
由于它提供了 的备份__str__
,如果您只能写一个,请从__repr__
这是关于的内置帮助repr
:
repr(...)
repr(object) -> string
Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.
也就是说,对于大多数对象,如果您输入由 打印的内容repr
,您应该能够创建一个等效的对象。但这不是默认实现。
默认实现__repr__
默认对象__repr__
是(C Python 源)类似于:
def __repr__(self):
return '<{0}.{1} object at {2}>'.format(
self.__module__, type(self).__name__, hex(id(self)))
这意味着默认情况下,您将打印对象来自的模块、类名以及其在内存中位置的十六进制表示 - 例如:
<__main__.Foo object at 0x7f80665abdd0>
这些信息不是很有用,但是没有办法推导出如何准确地创建任何给定实例的规范表示,而且总比没有好,至少告诉我们如何在内存中唯一地识别它。
怎么可能__repr__
有用?
让我们看看它有多么有用,使用 Python shell 和datetime
对象。首先我们需要导入datetime
模块:
import datetime
如果我们datetime.now
在 shell 中调用,我们将看到重新创建等效日期时间对象所需的一切。这是由 datetime 创建的__repr__
:
>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
如果我们打印一个日期时间对象,我们会看到一种很好的人类可读(实际上是 ISO)格式。这是由 datetime 实现的__str__
:
>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951
重新创建我们丢失的对象是一件简单的事情,因为我们没有通过从__repr__
输出中复制和粘贴将其分配给变量,然后打印它,并且我们在与另一个对象相同的人类可读输出中得到它:
>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180
我如何实施它们?
在开发过程中,如果可能,您将希望能够以相同的状态重现对象。例如,这就是 datetime 对象的定义方式__repr__
(Python 源代码)。它相当复杂,因为复制这样一个对象所需的所有属性:
def __repr__(self):
"""Convert to formal string, for repr()."""
L = [self._year, self._month, self._day, # These are never zero
self._hour, self._minute, self._second, self._microsecond]
if L[-1] == 0:
del L[-1]
if L[-1] == 0:
del L[-1]
s = "%s.%s(%s)" % (self.__class__.__module__,
self.__class__.__qualname__,
", ".join(map(str, L)))
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
if self._fold:
assert s[-1:] == ")"
s = s[:-1] + ", fold=1)"
return s
如果您希望您的对象具有更易读的表示,您可以实现__str__
next。这是 datetime 对象(Python 源代码)的实现__str__
方式,它很容易做到,因为它已经具有以 ISO 格式显示它的功能:
def __str__(self):
"Convert to string, for str()."
return self.isoformat(sep=' ')
设置__repr__ = __str__
?
这是对此处建议设置的另一个答案的批评__repr__ = __str__
。
Setting __repr__ = __str__
is silly -__repr__
是__str__
和 a的后备__repr__
,为开发人员在调试中使用而编写,应该在编写 a 之前编写__str__
。
__str__
仅当您需要对象的文本表示时才需要。
结论
为您编写的对象定义__repr__
,以便您和其他开发人员在开发时使用它时有一个可重现的示例。定义__str__
何时需要人类可读的字符串表示。
在 Hans Petter Langtangen 所著的Python scripting for Computing Science一书的第 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'
除了给出的所有答案,我想补充几点:-
1)__repr__()
当您简单地在交互式 python 控制台上写入对象的名称并按 Enter 时调用。
2)__str__()
当您使用带有 print 语句的对象时调用。
3)如果__str__
缺少,则打印和任何使用对象str()
调用__repr__()
的函数。
4)__str__()
容器,当被调用时将执行__repr__()
其包含的元素的方法。
5)在没有基本情况的情况下str()
调用 within__str__()
可能会递归,并且最大递归深度会出错。
6)__repr__()
可以调用repr()
它将尝试自动避免无限递归,将已经表示的对象替换为...
.
(2020 项)
问:__str__()
和有什么区别__repr__()
?
长
这个问题已经存在了很长时间,并且有各种各样的答案,其中大多数是正确的(更不用说来自几个 Python 社区的传说[!])。然而,当涉及到细节时,这个问题类似于询问内置函数str()
和repr()
内置函数之间的区别。我将用我自己的话来描述这些差异(这意味着我可能从Core Python Programming中“借用”了很多东西,所以请原谅我)。
两者 str()
都有repr()
相同的基本工作:它们的目标是返回 Python 对象的字符串表示形式。什么样的字符串表示是它们的区别。
str()
&__str__()
返回对象的可打印字符串表示形式...人类可读/供人类消费的东西repr()
&__repr__()
返回一个对象的字符串表示,它是一个有效的 Python 表达式,一个你可以传递给eval()
或输入到 Python shell 中而不会出错的对象。
例如,让我们分配一个字符串 tox
和一个int
to 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
显然你可以为 aint
但不一定为 a 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'
,虽然是该字符串的可打印字符串表示形式,但它不可评估,但"'foo'"
可以。是由或调用123
的有效 Python 。当我们用这些调用时会发生什么?int
str()
repr()
eval()
>>> eval('123')
123
>>> eval("'foo'")
'foo'
它之所以有效,是因为123
并且'foo'
是有效的 Python 对象。另一个关键要点是,虽然有时两者都返回相同的东西(相同的字符串表示),但情况并非总是如此。(是的,是的,我可以去创建一个有效的变量foo
,eval()
但这不是重点。)
关于这两对的更多事实
- 有时,
str()
并且repr()
被隐式调用,意味着它们是代表用户调用的:当用户执行print
(Py1/Py2)或调用print()
(Py3+)时,即使用户没有str()
显式调用,这样的调用也是在显示对象。 - 在 Python shell(交互式解释器)中,如果您在
>>>
提示符处输入变量并按 RETURN,则解释器会显示repr()
对该对象隐式调用的结果。 - 要连接
str()
andrepr()
到__str__()
and__repr__()
,实现对内置函数的调用,即,str(x)
或repr(y)
导致调用其对象的相应特殊方法:x.__str__()
或y.__repr()__
- 通过为您的
__str__()
Python 类实现and ,您可以重载内置函数 ( and ),从而允许将类的实例传递给and 。当发出这样的呼叫时,他们转身呼叫班级'和(根据#3)。__repr__()
str()
repr()
str()
repr()
__str__()
__repr__()
简而言之:
__str__
用于显示对象的字符串表示形式,以便其他人轻松阅读。
__repr__
用于显示对象的字符串表示。
假设我想创建一个Fraction
类,其中分数的字符串表示为“(1/2)”,对象(分数类)表示为“分数(1,2)”
所以我们可以创建一个简单的 Fraction 类:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
来自effbot的(非官方)Python 参考 Wiki(存档副本):
__str__
"计算对象的“非正式”字符串表示。这不同于__repr__
它不必是有效的 Python 表达式:可以使用更方便或更简洁的表示。 "
老实说,eval(repr(obj))
从未使用过。如果你发现自己在使用它,你应该停止,因为eval
它很危险,而且字符串是一种非常低效的序列化对象的方法(pickle
改用它)。
因此,我建议设置__repr__ = __str__
. 原因是对元素的str(list)
调用repr
(我认为这是 Python 3 未解决的最大设计缺陷之一)。实际repr
的输出可能不会很有帮助print([your, objects])
。
为了证明这一点,根据我的经验,该repr
函数最有用的用例是将一个字符串放在另一个字符串中(使用字符串格式)。这样,您不必担心转义引号或任何东西。但请注意,这里没有eval
发生任何事情。
str
- 从给定对象创建一个新的字符串对象。
repr
- 返回对象的规范字符串表示。
区别:
字符串():
- 使对象可读
- 为最终用户生成输出
代表():
- 需要重现对象的代码
- 为开发人员生成输出
来自《流利的 Python 》一书:
Python 对象的一个基本要求是提供其自身的可用字符串表示,一个用于调试和日志记录,另一个用于向最终用户展示。这就是为什么
特殊方法__repr__
和__str__
数据模型中存在的原因。
您可以从此代码中获得一些见解:
class Foo():
def __repr__(self):
return("repr")
def __str__(self):
return("str")
foo = Foo()
foo #repr
print(foo) #str
__str__
优秀的答案已经涵盖了和之间的区别__repr__
,对我来说,归结为前者即使是最终用户也可以阅读,而后者对开发人员来说尽可能有用。鉴于此,我发现 的默认实现__repr__
通常无法实现此目标,因为它忽略了对开发人员有用的信息。
出于这个原因,如果我有一个足够简单的__str__
,我通常只是尝试通过以下方式获得两全其美:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
__str__
可以通过调用在对象上调用str(obj)
,并且应该返回人类可读的字符串。
__repr__
可以通过调用在对象上调用repr(obj)
,并且应该返回内部对象(对象字段/属性)
这个例子可能会有所帮助:
class C1:pass
class C2:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
class C3:
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
class C4:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
ci1 = C1()
ci2 = C2()
ci3 = C3()
ci4 = C4()
print(ci1) #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2) #C2 class str
print(str(ci2)) #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3) #C3 class repr
print(str(ci3)) #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4) #C4 class str
print(str(ci4)) #C4 class str
print(repr(ci4)) #C4 class repr
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
何时print()
调用decimal.Decimal(23) / decimal.Decimal("1.05")
原始数字的结果;此输出为字符串形式,可以使用__str__()
. 如果我们简单地输入表达式,我们会得到一个decimal.Decimal
输出——这个输出是表示形式的,可以用__repr__()
. 所有 Python 对象都有两种输出形式。字符串形式被设计成人类可读的。表示形式旨在产生输出,如果将其提供给 Python 解释器将(如果可能)再现表示的对象。
要记住的一件重要事情是容器
__str__
使用包含的对象__repr__
。
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
Python 倾向于明确性而不是可读性,__str__
调用 atuple
调用包含的对象' __repr__
,对象的“正式”表示。尽管正式表示比非正式表示更难阅读,但它是明确的,并且对错误更健壮。
简而言之:
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'
完全理解__str__
并__repr__
直观地和永久地区分它们。
__str__
返回给定对象的字符串伪装体,以便眼睛可读
__repr__
返回给定对象的真实肉体(返回自身),以便明确识别。
在一个例子中看到它
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
至于__repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
我们可以__repr__
方便地对结果进行算术运算。
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
如果将操作应用于__str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
只返回错误。
另一个例子。
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
希望这可以帮助您建立具体的基础以探索更多答案。
__str__
必须返回字符串对象,而__repr__
可以返回任何 python 表达式。- 如果
__str__
缺少实现,则将__repr__
函数用作后备。如果__repr__
缺少函数实现,则没有后备。 - 如果
__repr__
函数返回对象的字符串表示,我们可以跳过__str__
函数的实现。
来源:https ://www.journaldev.com/22460/python-str-repr-functions
__repr__
print
在任何地方都可以使用,除了 bystr
方法(当 a__str__
被定义时!)
每个对象都继承__repr__
自所有对象创建的基类。
class Person:
pass
p=Person()
如果你打电话repr(p)
,你会默认得到这个:
<__main__.Person object at 0x7fb2604f03a0>
但是如果你打电话str(p)
,你会得到相同的输出。这是因为当__str__
不存在时,Python调用__repr__
让我们实现我们自己的__str__
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def __repr__(self):
print("__repr__ called")
return f"Person(name='{self.name}',age={self.age})"
p=Person("ali",20)
print(p)
并将str(p)
返回
__repr__ called
Person(name='ali',age=20)
让我们添加__str__()
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
print('__repr__ called')
return f"Person(name='{self.name}, age=self.age')"
def __str__(self):
print('__str__ called')
return self.name
p=Person("ali",20)
如果我们调用print(p)
and str(p),它会调用__str__()
所以它会返回
__str__ called
ali
repr(p)
将返回
repr称为“人(姓名='ali,年龄=self.age')”
让我们省略__repr__
并执行__str__
.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
print('__str__ called')
return self.name
p=Person('ali',20)
print(p)
将寻找__str__
并返回:
__str__ called
ali
注意=如果我们有__repr__
并__str__
定义,f'name is {p}'
将调用__str__