当前位置: 首页 > 面试题库 >

用多重继承调用父类__init__,正确的方法是什么?

方轩昂
2023-03-14
问题内容

假设我有多个继承方案:

class A(object):
    # code for A here

class B(object):
    # code for B here

class C(A, B):
    def __init__(self):
        # What's the right code to write here to ensure 
        # A.__init__ and B.__init__ get called?

有编写的两个典型方法C__init__

  1. (老式) ParentClass.__init__(self)
  2. (较新的样式) super(DerivedClass, self).__init__()

但是,无论哪种情况,如果父类(AB)没有遵循相同的约定,则代码将无法正常工作(某些代码可能会丢失,或被多次调用)。

那么又是什么正确的方法呢?说“保持一致,遵循一个或另一个”很容易,但是如果AB来自第三方图书馆,那又如何呢?有没有一种方法可以确保所有父类构造函数都被调用(以正确的顺序,并且只能调用一次)?

编辑:看看我的意思,如果我这样做:

class A(object):
    def __init__(self):
        print("Entering A")
        super(A, self).__init__()
        print("Leaving A")

class B(object):
    def __init__(self):
        print("Entering B")
        super(B, self).__init__()
        print("Leaving B")

class C(A, B):
    def __init__(self):
        print("Entering C")
        A.__init__(self)
        B.__init__(self)
        print("Leaving C")

然后我得到:

Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C

请注意,B的init被调用了两次。如果我做:

class A(object):
    def __init__(self):
        print("Entering A")
        print("Leaving A")

class B(object):
    def __init__(self):
        print("Entering B")
        super(B, self).__init__()
        print("Leaving B")

class C(A, B):
    def __init__(self):
        print("Entering C")
        super(C, self).__init__()
        print("Leaving C")

然后我得到:

Entering C
Entering A
Leaving A
Leaving C

请注意,B永远不会调用init。因此,似乎除非我知道/控制我从(AB)继承的类的初始化,否则我无法对正在编写的类(C)做出安全选择。


问题答案:

两种方法都可以正常工作。使用的方法super()为子类带来更大的灵活性。

在直接呼叫方式中,C.__init__可以同时呼叫A.__init__B.__init__

在使用时super(),需要将类设计为协作多重继承whereC调用super,这将调用A的代码,该代码也将调用super,从而调用B的代码。请参阅http://rhettinger.wordpress.com/2011/05/26/super-
considered-super
,以详细了解可以使用进行的操作super

[回答问题,稍后编辑]

因此,似乎除非我知道/控制我从(A和B)继承的类的初始化,否则我无法对我正在编写的类(C)做出安全的选择。

参考的文章显示了如何通过在A和周围添加包装器类来处理这种情况B。标题为“如何合并非合作类”的部分提供了一个可行的示例。

可能希望多重继承更容易,让您轻松组成Car和Airplane类来获得FlyingCar,但现实情况是,单独设计的组件通常需要适配器或包装器,然后才能像我们希望的那样无缝地组装在一起:-)

另一个想法:如果您对使用多重继承来编写功能不满意,则可以使用composition来完全控制在哪些情况下调用哪种方法。



 类似资料:
  • 本文向大家介绍python中子类继承父类的__init__方法实例,包括了python中子类继承父类的__init__方法实例的使用技巧和注意事项,需要的朋友参考一下 前言 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。 注意:这个名称的开始和结尾都是

  • 我有一个扩展了B类的a类。 A是这样定义的,它也覆盖了B的方法: B是这样定义的: 因此,如果我初始化A的一个对象,构造函数将调用调用方法doSomething()的超类之一。但哪一个会被处决?B的实现还是A中被重写的实现?

  • 问题内容: 假设我有以下两个课程 如果我启动一个beta类型的新对象,如何执行在alpha类而不是beta中找到的逻辑?我可以使用<-我想知道是否可行。 Eclipse IDE中的自动键入功能使我可以选择从class 或class中进行选择。 问题答案: 你可以做: 注意,这是对父级的引用,但是super()是它的构造函数。

  • 我在一个容器中存储了一个指向一组异构对象的指针列表,使用一个字符串来标识它们。关于这次行动的安全性,我已经在这里讨论过了,我没意见。 问题是,当类有多重继承,并且我试图将同一个指针转换到一个或另一个超类时,第二次转换似乎会失败。 下面是一个示例: 预期产出将是: 但我得到的却是: 我什至不知道这怎么可能,因为我什至没有打。 编辑在理解了这个页面的副本中讨论的内容后,我最终得到了这个解决方案: 我发

  • 嘿,我正在尝试调用子类方法(ChildClass扩展了超类()) 它没有看到ChildClass方法,我只能调用SuperClass()中的方法,我知道这可能是一个愚蠢的问题,但无论如何干杯

  • 问题内容: 我有一个带有很多参数的基类: 所有继承类都应运行基类的方法。 我可以在每个继承的类中编写一个将调用超类的方法,但这将是严重的代码重复: 自动调用超类的最Pythonic方法是什么? 问题答案: 如果有助于解决您的噩梦,请考虑使用 args和* kw。