Python 多重继承如何处理super()和不同的_uinit__;()参数?

Python 多重继承如何处理super()和不同的_uinit__;()参数?,python,class,constructor,multiple-inheritance,super,Python,Class,Constructor,Multiple Inheritance,Super,我只是在钻研一些更高级的python主题(至少对我来说是高级的)。我现在正在阅读有关多重继承以及如何使用super()。我或多或少了解超级函数的使用方式,但是这样做有什么不对呢 class First(object): def __init__(self): print "first" class Second(object): def __init__(self): print "second" class Third(First, Seco

我只是在钻研一些更高级的python主题(至少对我来说是高级的)。我现在正在阅读有关多重继承以及如何使用super()。我或多或少了解超级函数的使用方式,但是这样做有什么不对呢

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(),表示:

当派生类继承时,super()的用法也将正确 来自多个基类,其中部分或全部具有init 方法

因此,我将上面的示例改写如下:

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"
但是,它只运行它能找到的第一个init,它位于
first
(2)可以使用
super()
第一个
第二个
运行init,如果可以,如何运行
super(第三个,self)。\uu init(self)
两次只运行第一次。init()两次

再加上一些混乱。如果继承的类'init()函数采用不同的参数会怎么样。例如,如果我有这样的东西怎么办:

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:

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(方法解析顺序)

请参阅以下代码,这是菱形层次结构

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()
它打印:

d
b
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
d
B
[, , ]
python的MRO将是D、B、C、A

如果B没有init方法,那么它会选择C


3) 您无法做到所有方法都需要相同的签名。

那么您的意思是super()的使用取决于继承类中super()的使用?如果我不控制继承的类怎么办?然后我会简单地做第一个,第二个,就像我的第一个例子一样,是的,“超级”是一个协作过程,所有类都需要使用这个机制,否则它就不工作了。您可以在这里找到更多信息:是的,如果层次结构中的类不使用super,我认为您必须使用“旧式”方式:)谢谢。最后一个问题;为什么super()会添加到语言中?与“旧样式”相比,它有什么优势?我看到两个优势:不必显式引用父类,在多重继承的情况下,不必调用多个父构造函数。。。同样在python3中,您只需要调用super().something()而不是super(Class,self).something(),您可以说:“在多重继承的情况下,您不必调用多个父构造函数”。但是我不明白,因为如果我调用super(CurrentClass,self)。\uuuu init\uuuu()(就像我在第二段代码中所做的那样),它只运行第一个继承类的init函数,而不是所有继承类的init函数。这意味着在执行多重继承时不能使用super()。。对吗?
super(Class,self)
返回一个对象,所以不应该用
\uuu init\uuuuuuu(self)
调用它,而只需
\uuu init\uuuuu()
。您可以在答案中看到这一点,但是您最初的第一个代码返回exception
TypeError:\uuuu init\uuuu()正好接受1个参数(给定2个)