How does multiple inheritance work with the super() and different __init__() arguments?
我只是在潜入一些更高级的Python主题(好吧,至少对我来说是高级的)。我现在正在阅读关于多重继承以及如何使用super()。我或多或少理解超级函数的使用方式,但是(1)这样做有什么问题?:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class First(object): def __init__(self): print"first" class Second(object): def __init__(self): print"second" class Third(First, Second): def __init__(self): First.__init__(self) Second.__init__(self) print"that's it" |
关于super(),andrew kuchlings在python warts上的论文说:
usage of super() will also be correct when the Derived class inherits
from multiple base classes and some or all of them have init
methods
因此,我重写了上面的示例,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 | class First(object): def __init__(self): print"first" class Second(object): def __init__(self): print"second" class Third(First, Second): def __init__(self): super(Third, self).__init__(self) print"that's it" |
然而,这只运行它能找到的第一个in it,它在
增加一些混乱。如果继承类的init()函数采用不同的参数会怎么样?例如,如果我有这样的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class First(object): def __init__(self, x): print"first" class Second(object): def __init__(self, y, z): print"second" class Third(First, Second): def __init__(self, x, y, z): First.__init__(self, x) Second.__init__(self, y, z) print"that's it" |
(3)如何使用super()为不同继承类init函数提供相关参数?
欢迎使用所有提示!
另外,由于我有几个问题,我把它们加粗并编号。
对于问题2,您需要在每个类中调用super:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class First(object): def __init__(self): super(First, self).__init__() print"first" class Second(object): def __init__(self): super(Second, self).__init__() print"second" class Third(First, Second): def __init__(self): super(Third, self).__init__() print"that's it" |
对于问题3,这不可能做到,您的方法需要具有相同的签名。但是您可以忽略父类中的一些参数或使用关键字参数。
1)像你在1中所做的那样,没有什么错,如果你想使用基类的属性,那么你必须调用基类init(),或者即使你使用的是来自使用自己类属性的基类的方法,你也必须调用基类init()。
2)不能使用super从第一个和第二个运行init,因为python使用mro(方法解析顺序)
请参见以下代码这是菱形层次结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class A(object): def __init__(self): self.a = 'a' print self.a class B(A): def __init__(self): self.b = 'b' print self.b class C(A): def __init__(self): self.c = 'c' print self.c class D(B,C): def __init__(self): self.d = 'd' print self.d super(D, self).__init__() d = D() print D.mro() |
它打印:
1 2 3 | d b [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] |
python的mro是d,b,c,a
如果B没有init方法,它将指向C。
3)您不能这样做,所有方法都需要具有相同的签名。