猿问

具有 kwargs 的多重继承

问题

我在Dusty Phillips的面向对象编程中遇到了这个代码(为简洁起见进行了简化),我不确定这个定义的特定部分。


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

问题

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

class B:

    def __init__(self, b):

        self.b = b

难道不是多余的,因为任何盈余传递到都会传递到,提高?super().__init__(**kwargs)class BkwargsCobject

TypeError:object.__init__() 只接受一个参数(要初始化的实例)


这是否是如果被定义为而不是?Cclass C(B, A)class C(A, B)


大话西游666
浏览 122回答 3
3回答

海绵宝宝撒

考虑如何实例化:Cc = C(a=3, b=5, c=9)C.__init__获取所有关键字参数,但仅将关键字参数用于其自己的参数。其余的将传递给链中的下一个方法。在本例中,即 ,它“拉出”的参数并传递给 。 使用它并将(现在为空的)关键字参数集传递给下一个方法 。由于所有关键字参数都已“声明”并由其他类处理,因此会成功。c__init__A.__init__abB.__init__Bobject.__init__object.__init__由于 MRO 的构造方式,正确使用的类保证在调用时集体为空。super()**kwargsobject.__init__

慕森王

由于方法解析顺序为 ,可以按以下方式定义吗?(__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)的 MRO 是 ,所以必须调用,否则不会被调用。E(E, C, A, B, D, object)Bsuper().__init__D.__init__难道不是多余的,因为任何盈余传递到都会传递到,提高?super().__init__(**kwargs)class BkwargsCobject不,因为在上面的例子中,盈余将流向。但即使没有这个,当你调用一个参数太多构造函数时,引发错误也不是多余的;最好有一条错误消息通知您不正确的代码,而不是让错误未被发现。kwargsD.__init__这是否是如果被定义为而不是?Cclass C(B, A)class C(A, B)从某种意义上说,当然;但实际上,它是在任何类层次结构中发生的保护措施,只要层次结构中的其他类遵循相同的调用规则。Bsuper().__init__(**kwargs)

DIEA

在这个例子中,如果它像你说的那样定义(第1点)并且是原样的(并且没有其他用途),那么它的工作原理是一样的。BC至于第2点:如果还剩下关键字参数,那么对构造函数的调用确实会失败,例如:super()c = C(a=1, b=2, c=3, d=4)# -> TypeError: object.__init__() takes exactly one argument (the instance to initialize)由于该类(最初)是编写的,因此如果像您所说的那样以相反的顺序使用,或者如果有一个(或)多个超类(es),也是可以的,例如:Bclass D:    def __init__(self, d, **kwargs):        super().__init__(**kwargs)        self.d = dclass C(A,B,D):    ...
随时随地看视频慕课网APP

相关分类

Python
我要回答