具有多重继承的 Python super().__init__()

Posted

技术标签:

【中文标题】具有多重继承的 Python super().__init__()【英文标题】:Python super().__init__() with multiple inheritances 【发布时间】:2021-11-28 12:50:25 【问题描述】:
class School:
    def __init__(self, school_name):
        self._school = school_name

class Exam:
    def __init__(self, exam_name):
        self._exam_name = exam_name
    def credit(self):
        return 3

class Test(School, Exam):
    def __init__(self, school_name, exam_name):
        self._date = "Oct 7"
        super().__init__(school_name, exam_name)

test = Test('Success', 'Math')
print(test._school) 
print(test._exam_name) 

我只是想知道为什么 super().init() 不能在这里工作。如果我坚持使用super(),正确的做法是什么,才能成功通过school_name和exam_name。

【问题讨论】:

最大的问题是语义错误,导致代码混乱。考试不是一种学校。在这种情况下,组合更有意义。 super().__init__(school_name, exam_name) 不起作用,因为继承的实现都不接受两个(三个,self)参数。他们也没有自己调用super,所以无论如何只有一个会被调用。 如果你有一个实例方法(对于__init__来说通常如此)你需要获取类,一个简单的方法就是type(self),那么你可以访问__mro__属性,它是您的类继承自的类的元组。从Test.__init__Exam 上调用__init__ 可能看起来像:type(self).__mro__[1].__init__(*args, **kwargs) 【参考方案1】:

超级函数仅从 MRO 顺序调用父类。根据这一点,您的首选课程将是 School 并且将调用 School 的 init。在调用 super().__init__(self,school_name) 时,您必须只提供 school_name 作为参数。但是如果你想调用特定的__init__(),那么最好使用<parent_class>.<method>(<parameters>)。如果您想同时调用这两个初始化函数,请尝试这样做:

class School:
    def __init__(self, school_name):
        self._school = school_name

class Exam:
    def __init__(self, exam_name):
        self._exam_name = exam_name
    def credit(self):
        return 3

class Test(School, Exam):
    def __init__(self, school_name, exam_name):
        self._date = "Oct 7"
        School.__init__(self,school_name)
        Exam.__init__(self,exam_name)

test = Test('Success', 'Math')
print(test._school) 
print(test._exam_name)

尝试这样做

【讨论】:

以上是关于具有多重继承的 Python super().__init__()的主要内容,如果未能解决你的问题,请参考以下文章

Python 的 super() 如何与多重继承一起工作?

多重继承如何与 super() 和不同的 __init__() 参数一起工作?

python--多重继承

python中多重继承与获取对象

python进阶四(类的继承)4-4 python中多重继承

多重继承和调用 super()