kwargs 的多重继承

Jos*_*r98 6 python oop multiple-inheritance

问题

我碰到这个代码就面向对象编程尘埃菲利普斯(简化为简洁起见),我不确定这个定义的特定部分。

class A:
    def __init__(self, a, **kwargs):
        super().__init__(**kwargs)
        self.a = a

class B:
    def __init__(self, b, **kwargs):
        super().__init__(**kwargs)
        self.b = b

class C(A, B):
    def __init__(self, c, **kwargs):
        super().__init__(**kwargs)
        self.c = c
Run Code Online (Sandbox Code Playgroud)

问题

  1. 由于方法解析顺序是(__main__.C, __main__.A, __main__.B, object),可以class B用以下方式定义吗?
class B:
    def __init__(self, b):
        self.b = b
Run Code Online (Sandbox Code Playgroud)
  1. 是不是super().__init__(**kwargs)class B多余的,因为任何多余的kwargs传递C将被传递到object,饲养?

类型错误:object.__init__() 只需要一个参数(要初始化的实例)

  1. 这是 ifC被定义为class C(B, A)而不是的保护措施class C(A, B)吗?

che*_*ner 5

考虑如何实例化C

c = C(a=3, b=5, c=9)
Run Code Online (Sandbox Code Playgroud)

C.__init__获取所有关键字参数,但仅将其用作自己的参数c。其余的将传递给__init__链中的下一个方法。在本例中,即A.__init__,它“拉出” 的参数a并传递bB.__init__B使用它并将(现在为空的)关键字参数集传递给下一个方法object.__init__。因为所有关键字参数都已被其他类“声明”并处理,所以object.__init__成功。

由于 MRO 的构造方式,正确使用super()保证的类在被调用时将被集体调用。**kwargsobject.__init__

  • 确保所有适用的 __init__ 都被调用并以正确的顺序调用是至关重要的;考虑一些继承自“C”的类“E”和仅继承自“A”的类“D”。“E”的 MRO 可能看起来像“[E,C,B,D,A,对象]”。如果没有“super”,对“E()”的调用不能确保“D.__init__”在“B.__init__”和“A.__init__”之间被调用,考虑到“B”不“知道”“D” `。 (2认同)

kay*_*ya3 3

由于方法解析顺序是(__main__.C, __main__.A, __main__.B, object),可以class B用以下方式定义吗?

不,因为这样就会失败:

class D:
    def __init__(self, d, **kwargs):
        self.d = d
        super().__init__(**kwargs)

class E(C, D):
    def __init__(self, e, **kwargs):
        self.e = e
        super().__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)

的MROE(E, C, A, B, D, object),所以B必须调用super().__init__,否则D.__init__不会被调用。

这不是多余super().__init__(**kwargs)的吗class B,因为kwargs传递给的任何盈余C都将传递给object, 提高?

不,因为盈余kwargs将用于D.__init__上面的示例中。但即使没有这一点,当您调用带有太多参数的构造函数时,引发错误也不是多余的;最好有一条错误消息通知您错误的代码,而不是让错误未被发现。

C这是 if被定义class C(B, A)为而不是的保障吗class C(A, B)

从某种意义上说,当然;但实际上,只要层次结构中的其他类遵循相同的调用规则,它就可以在任何类B层次结构中发生。super().__init__(**kwargs)