🔨 repr(obj, /)
该方法会返回 obj 的标准(canonical)字符串表示形式——可供解释器读取的表示形式。
对于大多数类型(包含大多数内置类型)来说,repr(obj)
返回的字符串应该像是一个有效的 Python 表达式,并且将该字符串传递给 evla()
后,可以创建一个具备相同值的对象(需给定恰当的环境),即 eval(repr(obj)) == obj
如果 repr(obj)
无法返回一个有效的表达式,则应返回形如 <...some useful description...>
的字符串,其中会包含对象的类型的名称和附加信息(对象的名称和地址)。
示例 - 观察 str
和 repr
的区别:
>>> value = 'orca_j35\n'
>>> str(value)
'orca_j35\n'
>>> repr(value)
"'orca_j35\\n'"
>>> eval(repr(value))
'orca_j35\n'
>>> eval(str(value))
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
eval(str(value))
File "<string>", line 1, in <module>
NameError: name 'orca_j35' is not defined
示例 - 无法返回有效表达式的情况:
>>> class Student:
def __init__(self,name):
self.name = name
>>> a = Student('Bob')
>>> repr(a)
'<__main__.Student object at 0x000001243768AEF0>'
当我们通过 repr(obj)
获取对象的标准字符串表示形式时,实际上在 repr()
内部会调用 type(obj).__repr__(obj)
来获取对象的字符串表示形式。因此,可通过覆写类中的 __repr__()
方法来控制 repr()
的返回值。
示例 - 覆写类中的 __repr__
方法:
>>> class Cls:
def __repr__(self):
return 'Cls类的实例:{}'.format(super().__repr__())
>>> repr(Cls())
'Cls类的实例:<__main__.Cls object at 0x0000012437522FD0>'
# 如没有覆写__str__,同样会调用__repr__
>>> str(Cls())
'Cls类的实例:<__main__.Cls object at 0x00000124375C89E8>'
示例 - 如果 __repr__
和 __str__
相同,可直接写作 __repr__ = __str__
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__
实现细节
repr(obj)
会在内部调用 type(obj).__repr__(obj)
,从而使用类字典中的 __repr__()
方法来获取 obj 的标准字符串表示形式。也就是说在获取属性列表时,会跳过实例字典:
class Cls:
def __repr__(self):
return super().__repr__()
obj = Cls()
from types import MethodType
obj.__repr__ = MethodType(lambda self: '绑定到实例的__repr__方法', obj)
print(repr(obj))
'''Out:
<__main__.Cls object at 0x000001F0D7A35470>
'''
如果仅考虑类和实例,这好像并没有什么意义,因为不会有人在实例字典中重新绑定 __repr__
方法。但是,如果考虑到元类和类,这就很有意义了。类是元类的实例,当 obj 是一个类时,实际上需要调用元类中的 __repr__
方法,此时我们便需要跳过类字典中 __repr__
方法,使用元类中的同名方法。
__repr__
🔨 object.__repr__(self)
该方法会返回对象的正式的(official)字符串表示形式(可供解释器读取的表示形式),其返回值必须是一个字符串对象。repr()
函数会在内部调用该方法。
通常来说,__repr__
返回的字符串应该像是一个有效的 Python 表达式,并且可用该字符串重新创建一个具备相同值的对象(需给定恰当的环境)。
如果 __repr__
无法返回一个有效的表达式,则应返回形如 <...some useful description...>
的字符串,其中会包含对象的类型的名称和附加信息(对象的名称和地址)。
如果在某个类中覆写了 __repr__
,但并没有覆写 __str__
。那么当需要该类的实例的"非正式(informal)"的字符串表示形式时,也会调用 __repr__()
。
通常会在调试时使用 __repr__
,因此在描述对象时最重要的是提供丰富的信息和明确的含义。
网友评论