3 回答
TA贡献1809条经验 获得超8个赞
考虑如何实例化:C
c = C(a=3, b=5, c=9)
C.__init__
获取所有关键字参数,但仅将关键字参数用于其自己的参数。其余的将传递给链中的下一个方法。在本例中,即 ,它“拉出”的参数并传递给 。 使用它并将(现在为空的)关键字参数集传递给下一个方法 。由于所有关键字参数都已“声明”并由其他类处理,因此会成功。c
__init__
A.__init__
a
b
B.__init__
B
object.__init__
object.__init__
由于 MRO 的构造方式,正确使用的类保证在调用时集体为空。super()
**kwargs
object.__init__
TA贡献1777条经验 获得超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)
的 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)
TA贡献1820条经验 获得超2个赞
在这个例子中,如果它像你说的那样定义(第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),也是可以的,例如:B
class D:
def __init__(self, d, **kwargs):
super().__init__(**kwargs)
self.d = d
class C(A,B,D):
...
添加回答
举报