[英]Calling super class method in multiple inheritance
I have the following code: 我有以下代码:
class A:
pass
class B(A):
def foo(self, a):
if a:
return 'B'
return super(B, self).foo(a)
class C:
def foo(self, a):
return 'C'
class D(B, C):
def foo(self, a):
return super().foo(a)
d = D()
print(d.foo(0))
When I call d.foo(0)
based on MRO it first calls the foo
method of B
class and inside that, if the condition is wrong and it will return super(B, self).foo(0)
but class A
has no foo method and I expect this error: 当我基于MRO调用d.foo(0)
,它首先调用B
类的foo
方法,并且在其中,如果条件错误,它将返回super(B, self).foo(0)
但类A
没有foo方法,我预计会出现此错误:
AttributeError: 'super' object has no attribute 'foo'
but it returns 'C'
from class C
. 但它从类C
返回'C'
。 Why? 为什么?
super()
searches the MRO for the next class that has the attribute; super()
在MRO中搜索具有该属性的下一个类 ; that A
doesn't implement it doesn't matter as C
is still considered. A
没有实现就没有关系,因为仍在考虑C
For D
, the MRO is D
, B
, A
, C
: 对于D
,MRO为D
, B
, A
, C
:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)
so super().foo
in D
will find B.foo
, and from B.foo
, A
is skipped and C.foo
is found; 因此D
super().foo
将找到B.foo
,并且从B.foo
中跳过A
并找到C.foo
; you can test this yourself from the interactive interpreter: 您可以从交互式解释器中对此进行测试:
>>> super(D, d).foo
<bound method B.foo of <__main__.D object at 0x1079edb38>>
>>> super(B, d).foo
<bound method C.foo of <__main__.D object at 0x1079edb38>>
This is what a Python implementation of the attribute search algorithm would look like: 这是属性搜索算法的Python实现如下所示:
def find_attribute(type_, obj, name):
starttype = type(obj)
mro = iter(starttype.__mro__)
# skip past the start type in the MRO
for tp in mro:
if tp == type_:
break
# Search for the attribute on the remainder of the MRO
for tp in mro:
attrs = vars(tp)
if name in attrs:
res = attrs[name]
# if it is a descriptor object, bind it
descr = getattr(type(res), '__get__', None)
if descr is not None:
res = descr(
res,
None if obj is starttype else obj,
starttype)
return res
where type_
is the first argument to super()
(the class the method is defined on), obj
is the instance (so type(d)
here), and name
is the attribute you are looking for. 其中, type_
是super()
的第一个参数super()
定义方法的类), obj
是实例(此处为type(d)
),而name
是您要查找的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.