python中多重继承中的超函数

super function in Multiple inheritance in python

我已经用Python3.4编写了这段代码并使用了类。我已经用super()函数在这段代码中实现了多个继承。我想调用library类的init()函数。但是我不能,有人能告诉我这个错误吗?

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
class college:
    def __init__(self, rollno):
        print("Roll no:", rollno)

class library:
    def __init__(self, libcardno):
        print("Library card no:", libcardno)

class student(college, library):
    def __init__(self, name):
        print("Name:", name)
        super().__init__(5560)
        super().__init__(60)

输出

1
2
3
4
>>> obj = student("John")
Name: John
Roll no: 5560
Roll no: 60

只要理解这个问题,它不是另一个问题的复制品。


可以直接调用各自父类的__init__方法。

1
2
3
4
5
class student(college, library):
    def __init__(self, name):
        print("Name:", name)
        college.__init__(self,5560)
        library.__init__(self,60)


Short:

你不能也不需要用super()来调用不同形式的__init__。当然有办法,但我不推荐这样做。

长:

python使用要从中继承的类的列表。你可以看到这个列表ClassName.__mro__mro代表Method Resolution Order

想想看,你有三个等级:ClassAClassBClassCClassC延伸ClassAClassB(如果你使用python2、ClassAClassB必须从object延伸。

1
class ClassC(ClassA, ClassB):

那么,ClassC.__mro__如下:

1
(<class '__main__.ClassC'>, <class '__main__.ClassA'>, <class '__main__.ClassB'>, <class 'object'>)

所以python继承了ClassCClassAClassB的顺序。它假设方法在这个列表中有相同的形式。这就是为什么你不能使用不同形式的__init__调用来使用super()

如果您需要使用super(),并且没有选择,您可以考虑将参数传递为**kwargs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ClassA():
    def __init__(self, **kwargs):
        super(ClassA, self).__init__(**kwargs)
        print("Class A Initialized:", kwargs['a'])

class ClassB():
    def __init__(self, **kwargs):
        # super(ClassA, self).__init__(**kwargs)
        # if you call above, you'll get type error, because above will call object.__init__ which takes only 1 argument
        print("Class B Initialized:", kwargs['b'])

class ClassC(ClassA, ClassB):
    def __init__(self, **kwargs):
        super(ClassC, self).__init__(**kwargs)
        print("Class C Initialized:", kwargs['c'])

ClassC(a="A", b="B", c="C")

您可以得到以下输出:

1
2
3
Class B Initialized: B
Class A Initialized: A
Class C Initialized: C

但是,我还是建议不要使用这种继承形式,因为它非常复杂