我知道这里已经讨论过super()和多继承。但是我没有找到解决方案,关于我在python3中的具体问题。 我们假设我们有:
#! /usr/bin/env python3
class A(object):
def __init__(self):
super().__init__()
def foo(self):
print("The")
class B(object):
def __init__(self):
super().__init__()
def foo(self):
print("world")
class C(B):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("is")
class D(A,C):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
d = D()
d.foo()
这会让我:
The
nice
另一方面,如果我将D()中的继承顺序更改为:
class D(C,A):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
它给了我
world
is
nice
但是,我只能获得所需的输出:
The
world
is
nice
使用:
class D(C,A):
def __init__(self):
super().__init__()
def foo(self):
A.foo(self)
C.foo(self)
print("nice")
我发现它非常不优雅。
所以我的问题是:是否可以在python3中使用super()来调用两个超类的超级方法而不仅仅是第一个?
答案 0 :(得分:4)
不幸的是,如果不了解D
的方法解析顺序(MRO),则无法在super()
中调用D
来获取两者基类。
但MRO是强大的概念。在第二种情况下,
class D(C,A):
...
(MRO)
>>> D.mro()
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
正如调用super()
将您带到MRO的下一个班级,正如Pieters先生所说,并且您希望打印语句按A
,B
的顺序排列, C
,然后是D
,只需将super().foo()
放在print(...)
的每个定义中,然后foo()
秒。唯一的例外是不要将super().foo()
放在课程A
中,因为foo()
中未定义object
。
#! /usr/bin/env python3
class A(object):
def __init__(self):
super().__init__()
def foo(self):
print("The")
class B(object):
def __init__(self):
super().__init__()
def foo(self):
super().foo() # Inserted
print("world")
class C(B):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("is")
class D(C,A): # Correct ordering
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
d = D()
d.foo()
第一种情况下D(A,C)
的MRO也包括所有类,因此正确排序super()
和print(...)
语句,可以使其有效:
class A(object):
def foo(self):
print("The")
super().foo()
class B(object):
def foo(self):
print("world")
class C(B):
def foo(self):
super().foo()
print("is")
class D(A,C):
def foo(self):
super().foo()
print("nice")
D().foo()
要了解继承顺序(例如class D(C,A)
或class D(A,C)
)和MRO,请参阅https://www.python.org/download/releases/2.3/mro/。详细描述了C3方法的分辨率顺序,并且有很好的绘制的ASCII类层次结构,标有MRO。
答案 1 :(得分:2)
也许这会有所帮助
class A(object):
def __init__(self):
super().__init__()
def foo(self):
print("The")
if hasattr(super(), 'foo'):
super().foo()
class B(object):
def __init__(self):
super().__init__()
def foo(self):
print("world")
class C(B):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("is")
class D(A,C):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
d = D()
d.foo()
输出:
The
world
is
nice