【问题标题】:How do I initialize this derived class that uses multiple inheritance?如何初始化这个使用多重继承的派生类?
【发布时间】:2021-08-09 00:12:37
【问题描述】:

假设我有一个名为Vehicle 的类,我有两个子类BoatCar,它们继承自Vehicle

现在假设我有一辆两栖车辆,它使用多重继承AmphibiousVehicle(Boat, Car)

现在我的问题是:AmphibiousVehicle__init__函数应该如何定义?

BoatCar 都通过调用 super().__init__() 来初始化 Vehicle

是否需要在AmphibiousVehicle的init中一一初始化BoatCar

或者我可以打一次super 吗?如果我这样做,我看不到 Car 是如何被初始化的?

【问题讨论】:

    标签: python multiple-inheritance


    【解决方案1】:

    Python 使用协作多重继承。这意味着您对super() 的调用不一定会命中调用它的基类,它会从您开始的方法解析顺序 (MRO) 中命中下一个类。

    演示:

    class A:
        def __init__(self):
            print("A.__init__")
            super().__init__()
    
    class B:
        def __init__(self):
            print("B.__init__")
            super().__init__()
    
    class C(A, B):
        def __init__(self):
            print("C.__init__")
            super().__init__()
    
    c = C()
    

    给出输出:

    C.__init__
    A.__init__
    B.__init__
    

    所以在类A 中调用super().__init__() 在类B 中调用__init__(),即使类A 没有从类B 继承。

    只要你所有的班级都确保他们在适当的时候调用super,你只需要调用一次并相信一切都会合作。

    MRO 基本上是 python 在类中搜索方法或属性的顺序。您可以通过检查类的__mro__ 属性来检查此顺序:

    print(C.__mro__)
    

    给我们:

    (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
    

    【讨论】:

    • 但是如果A, B 本身都继承自AA, BB(在我的情况下是AA = BB)呢?那么他们的 init 什么时候会被调用呢?
    • 如果 A 和 B 都从 AA 继承,则 MRO 将是 C->A->B->AA(然后是隐含的 ->object)。您可以通过检查类的 __mro__ 属性来查询 MRO 是什么。
    • @sakuew2 如果CarBoat 在它们的init 中调用super().__init__,则Vehicle 的init 将被调用。因为,当他们调用 super.init 时,AmphibiousVehicle 调用 Car.init,后者调用 Boat.init,然后调用 Vehicle.init
    • 是的,没错,只要他们都打电话给super.__init__()
    • 好的,但这是我不明白的。你说Boat.init 打电话给Vehicle.init。但这意味着Car.init 不会调用Vehicle.init。这意味着可能有一个方法 IN Car 调用了 Vehicle 中的一个方法。那么会发生什么?该方法是否会自动推迟到“Boat”,然后再推迟到 Vehicle?
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 2021-08-02
    • 2010-09-20
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多