在python (3.5.2)中,我期望repr(obj)函数调用obj类的魔法方法__repr__()。然而,调用这两个函数似乎不会产生相同的结果。有谁能解释一下原因吗?
示例代码:
class parent:
def __init__(self):
self.a = "haha"
def __repr__(self):
return repr(self.a)
class child(parent):
def __init__(self):
super().__init__()
self.b="bebe"
def __repr__(self):
return "("+super().__repr__()+", "+repr(super())+", "+self.b+")"
def print1(self):
print("super().__repr__() returns:", super().__repr__())
print("repr(super()) returns:", repr(super()))
print("plom(super()).__repr__() returns:", plom(super()).__repr__())
print("repr(plom(super())) returns:", repr(plom(super())))
def plom(var):
return var
t=child()
print(t.__repr__())
print(repr(t))
print('-----')
t.print1()
print('-----')
print(plom(t).__repr__())
print(repr(plom(t)))结果:
>>>
RESTART: test super.py
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
-----
super().__repr__() returns: 'haha'
repr(super()) returns: <super: <class 'child'>, <child object>>
plom(super()).__repr__() returns: 'haha'
repr(plom(super())) returns: <super: <class 'child'>, <child object>>
-----
('haha', <super: <class 'child'>, <child object>>, bebe)
('haha', <super: <class 'child'>, <child object>>, bebe)
>>> 发布于 2018-11-24 10:36:35
调用repr(super())直接访问super类上的__repr__ (从技术上讲,这是定义super类型的C PyTypeObject结构的tp_repr )。大多数特殊的dunder方法在隐式调用时都是这样的(而不是显式地将它们作为方法调用)。repr(x)不等同于x.__repr__()。您可以将repr定义为:
def repr(obj):
return type(obj).__repr__(obj) # Call unbound function of class with instance as arg当你期待它的时候:
def repr(obj):
return obj.__repr__() # Call bound method of instance这种行为是有意为之的;首先,对每个实例定制Dunder方法意义不大,其次,禁止它允许在C级别上编写更有效的代码(它有更快的方式来完成上面说明性方法所做的事情)。
相比之下,super().__repr__()在super实例上查找方法,而super定义一个自定义tp_getattro (大致相当于定义一个自定义__getattribute__方法),这意味着在实例上的查找在找到类的tp_repr/__repr__之前被拦截,而是通过自定义属性getter (执行超类委托)分派。
发布于 2018-11-24 10:37:13
如果您查阅 the docs,您将看到super返回一个代理对象,该对象根据方法解析顺序将方法调用委托给适当的类。
因此,repr(super())为您提供了代理对象的表示。而方法调用super().__repr__()按照方法解析顺序给出了下一个类定义的表示。
如果您想要超类本身,请尝试
my_object.__mro__[1]发布于 2018-11-24 10:09:11
在super().__repr__()中,您将调用超级对象的repr类,因此您将获得'haha'
在第二个示例中,您将调用super()的repr。super()的输出是什么?<super: <class 'child'>, <child object>>所以您实际上是在某个类层次结构上调用repr
https://stackoverflow.com/questions/53454458
复制相似问题