32

我只是在深入研究一些更高级的 python 主题(好吧,至少对我来说是高级的)。我现在正在阅读有关多重继承以及如何使用 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"

关于 super(),Andrew Kuchlings 关于 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) 可super()用于运行 init 的 fromFirstSecond,如果可以,如何运行?运行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) 如何使用 super() 为不同的继承类 init 函数提供相关参数?

欢迎所有提示!

附言。由于我有几个问题,我将它们加粗并编号。

4

2 回答 2

12

对于问题 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,这是无法做到的,您的方法需要具有相同的签名。但是您可以忽略父类中的一些参数或使用关键字参数。

于 2013-05-31T10:51:22.130 回答
2

1)像你在1中所做的那样没有错,如果你想使用基类中的属性,那么你必须调用基类init(),或者即使你使用来自使用属性的基类的方法它自己的类然后你必须调用基类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)你不能这样做所有的方法都需要有相同的签名。

于 2013-11-14T09:51:57.443 回答