2011-06-09 54 views
1

我怎么能初始化倍数超类中的蟒蛇..初始化倍数超类蟒蛇

例如:

class A (B, C): 
    def __init__(self, param): 
     B.__init__(self) 
     C.__init__(self, param) 
    # 
# 
+3

你的问题到底是什么? – 2011-06-09 14:23:04

+6

您显示的代码有效。当然你知道这一点,因为你试过了,而不是用SO作为解释器。那你在问什么? – delnan 2011-06-09 14:28:34

回答

6

您的原始代码工作。它非常清晰和可读。呼叫签名是明确的,并允许您使用A(p)A(param=p)实例化A

class A(B, C): 
    def __init__(self, param): 
     B.__init__(self) 
     C.__init__(self, param) 

也可以使用super。它提供了有吸引力的能力有一个调用来替换 两个显式调用B.__init__C.__init__super(A,self).__init__

class B(object): 
    def __init__(self, **kwargs): 
     print('B') 
     super(B,self).__init__(**kwargs) 

class C(object): 
    def __init__(self, **kwargs): 
     print('C') 
     self.param=kwargs.pop('param',None) 
     super(C,self).__init__(**kwargs) 

class A(B, C): 
    def __init__(self, **kwargs): 
     print('A') 
     super(A,self).__init__(**kwargs) 

a=A(param=1) 

# A 
# B 
# C 

使用super,但是,需要一个rather heavy price

  1. __init__调用签名所有类别 必须是相同的。由于ACparam说法,但B 不,你必须修改所有 三到使用更明确(但 制服!)**kwargs说法。因此,呼叫签名不再是明确的。

  2. 现在A只能被实例化 与A(param=p),并且不再与A(p)

  3. 更糟(如斯文Marnach指出 出在评论),传递给A必须在某一点的每个参数被关闭的kwargs因为object弹出不接受任何参数。一旦类 (如C)弹出一个参数 的kwargs,没有其他类(如 B)可以使用相同的参数名称。因此,参数的命名需要所有类别之间的协调,即使理想情况下,BC应该彼此独立。

  4. 该代码有更多的锅炉板残余物 和并发症。 阅读起来不太容易。

因此,我一般喜欢避开super(一样你原来的代码),除非super远远超过上面提到的成本带来的间接。

+0

不错的总结。我想补充一点,这实际上*是一个带有'object'的继承钻石。 'super()'调用链最终会调用'object .__ init __(self,** kwargs)',所以你必须确保所有的参数在这个时候已经被'kwargs'弹出。这在两个类需要参数的情况下会产生问题,并且这个问题没有真正的解决方案。 – 2011-06-09 18:32:51

+0

@Sven Marnach:谢谢你用'super'指出这个额外的问题。 – unutbu 2011-06-09 18:46:15

+0

我不知道为什么超级被称为语言,使事情不明确,而对大多数使用不起作用。 – dashesy 2015-04-15 01:07:48