首页 文章

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

提问于
浏览
24

我只是潜入一些更高级的python主题(好吧,至少先进了我) . 我现在正在阅读有关多继承以及如何使用super()的内容 . 我或多或少了解超级函数的使用方式,但 (1) What's wrong with just doing it like this ?:

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 paper on Python Warts说:

当Derived类从多个基类继承并且其中一些或全部具有init方法时,super()的使用也将是正确的

所以我重写了上面的例子如下:

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) Can super() be used to run both the init's from First and Second, and if so, how? 运行 super(Third, self).__init__(self) 两次只运行First . 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) How would I be able to supply the relevant arguments to the different inherited classes init functions using super()?

欢迎所有提示!

PS . 由于我有几个问题,我把它们做成了大胆的编号 .

2 回答

  • 11

    对于问题2,您需要在每个 class 中调用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,无法完成,您的方法需要具有相同的签名 . 但你可以忽略父句中的一些参数或使用关键字参数 .

  • 2

    1)做你在1中所做的事情没有错,如果你想使用基类中的属性那么你必须调用基类 init ()或甚至你使用基类中使用属性的方法它自己的类然后你必须调用baseclass 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'>]
    

    python的MRO是D,B,C,A

    如果B没有init方法则转为C.

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

相关问题