在多重继承中调用 super class 方法
Calling super class method in multiple inheritance
我有以下代码:
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))
当我基于 MRO 调用 d.foo(0)
时,它首先调用 B
class 的 foo
方法,在其中,如果条件错误,它将 return super(B, self).foo(0)
但 class A
没有 foo 方法,我预计会出现此错误:
AttributeError: 'super' object has no attribute 'foo'
但它 returns 'C'
来自 class C
。为什么?
super()
在 MRO 中搜索 下一个 class 具有该属性; A
没有实现并不重要,因为 C
仍在考虑中。
对于 D
,MRO 为 D
、B
、A
、C
:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)
所以D
中的super().foo
会找到B.foo
,而从B.foo
开始,A
被跳过,找到C.foo
;你可以从交互式解释器中自己测试它:
>>> 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>>
属性搜索算法的 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
其中 type_
是 super()
的第一个参数(class 定义了方法),obj
是实例(所以 type(d)
此处),name
是您要查找的属性。
我有以下代码:
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))
当我基于 MRO 调用 d.foo(0)
时,它首先调用 B
class 的 foo
方法,在其中,如果条件错误,它将 return super(B, self).foo(0)
但 class A
没有 foo 方法,我预计会出现此错误:
AttributeError: 'super' object has no attribute 'foo'
但它 returns 'C'
来自 class C
。为什么?
super()
在 MRO 中搜索 下一个 class 具有该属性; A
没有实现并不重要,因为 C
仍在考虑中。
对于 D
,MRO 为 D
、B
、A
、C
:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)
所以D
中的super().foo
会找到B.foo
,而从B.foo
开始,A
被跳过,找到C.foo
;你可以从交互式解释器中自己测试它:
>>> 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>>
属性搜索算法的 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
其中 type_
是 super()
的第一个参数(class 定义了方法),obj
是实例(所以 type(d)
此处),name
是您要查找的属性。