假设类层次结构如下所示,并且 args 中的参数沿继承链传递,以便所有类都获得所需的参数:
class A(object):
def __init__(self, **args):
print('A.__init__')
self.a = args['a']
super(A, self).__init__(**args)
class B (object):
def __init__(self, **args):
print('B.__init__')
self.b = args['b']
# super(B, self).__init__(**args)
class C(A, B):
def __init__(self, **args):
print('C.__init__')
self.c = args['c']
super(C, self).__init__(**args)
c = C(a=1, b=2, c=3)
print(c.__dict__)
如果类 B 用 args 调用 super's __init__,即取消注释此行
# super(B, self).__init__(**args)
,则引发异常:
..., in __init__
super(B, self).__init__(**args)
TypeError: object.__init__() takes no parameters
MRO 中的最后一个类似乎无法调用 super's __init__,或者只能用零参数调用它。谁能解释为什么?
假设编码器 0 写入类 A 和 B,然后编码器 1 编写类 C 以扩展 A 和 B。由于编码员 0 不知道实际的 MRO,他怎么能决定哪个类应该用 args 调用 super's __init__,哪个类不应该?
或者有人会分享多重继承和参数传递的最佳实践吗?
A
和B
的基类是object
。object
是一个不带参数的类,因为它不对它们执行任何操作。(你不能写object(1)
,对吧?
解决此问题的最佳做法是在传递之前删除使用的参数。
class A(object):
def __init__(self, **args):
print('A.__init__')
self.a = args.pop("a")
super(A, self).__init__(**args)
class B (object):
def __init__(self, **args):
print('B.__init__')
self.b = args.pop("b")
super(B, self).__init__(**args)
class C(A, B):
def __init__(self, **args):
print('C.__init__')
self.c = args.pop("c") # permanently removes 'c' from args
super(C, self).__init__(**args)
c = C(a=1, b=2, c=3)
print(c.__dict__)