多继承如何与super()和不同的__init __()参数一起使用?

时间:2013-05-31 10:23:56

标签: python class constructor multiple-inheritance super

我只是潜入一些更高级的蟒蛇科目(好吧,至少向我发展)。我现在正在阅读有关多继承以及如何使用super()的内容。我或多或少地理解超级函数的使用方式,但(1)这样做有什么问题?:

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"

在超级()上,Andrew Kuchlings paper on Python Warts说:

  当Derived类继承时,

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()使用来自FirstSecond的初始化,如果是,那么如何?只运行super(Third, self).__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函数提供相关参数?

欢迎所有提示!

PS。因为我有几个问题,所以我们把它们做成了大胆的编号......

2 个答案:

答案 0 :(得分:11)

对于问题2,你需要在每个班级打电话给超级:

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 :(得分:2)

1)做你在1中所做的事情没有错,如果你想使用基类中的属性那么你必须调用基类 init (),或者即使你使用基类中使用自己类的属性的方法然后你必须调用baseclass init ()

2)你不能使用super从First和Second运行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'>]

python的MRO是D,B,C,A

如果B没有init方法,则转到C。

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