oop - python 用多重继承调用父类 __init__,正确的方法是什么?

  显示原文与译文双语对照的内容
75 4

假设我有一个多重继承方案:

class A(object):
 # code for A here
class B(object):
 # code for B here
class C(A, B):
 def __init__(self):
 # What's the right code to write here to ensure 
 # A.__init__ and B.__init__ get called?

下面是编写 C__init__的两种典型方法:

  • ( 旧样式) ParentClass.__init__(self)
  • ( 新样式)super(DerivedClass, self).__init__()

但是,无论哪种情况,如果父类的( AB ) 不遵循相同的约定,那么代码将无法正常工作,如。

那么正确的方法是什么?很容易说"保持一致,遵循一个或者另一个",但如果 A 或者 B 来自 3rd 个聚类库,那么?是否有一种方法可以确保所有父类构造函数都被称为( 按正确的顺序,只有一次)?

编辑:了解我的意思,如果我这样做:

class A(object):
 def __init__(self):
 print"entering A"
 super(A, self).__init__()
 print"leaving A"
class B(object):
 def __init__(self):
 print"entering B"
 super(B, self).__init__()
 print"leaving B"
class C(A, B):
 def __init__(self):
 print"entering c"
 A.__init__(self)
 B.__init__(self)
 print"leaving c"

然后我得到了:

entering c
entering A
entering B
leaving B
leaving A
entering B
leaving B
leaving c

请注意,B init被调用两次。如果我这样做:

class A(object):
 def __init__(self):
 print"entering A"
 print"leaving A"
class B(object):
 def __init__(self):
 print"entering B"
 super(B, self).__init__()
 print"leaving B"
class C(A, B):
 def __init__(self):
 print"entering c"
 super(C, self).__init__()
 print"leaving c"

然后我得到了:

entering c
entering A
leaving A
leaving c

请注意,永远不会调用 B init 。因这里,除非我知道/控制init是我从( AB ) 继承的类,但是我不能对所编写的类进行安全选择。

时间:原作者:0个回答

60 3

这两种方法都很好。使用 super()的方法会导致子类的GREATER 灵活性。

在直接调用方法中,C.__init__ 可以调用 A.__init__B.__init__

在使用 super() 时,类需要为协作多重继承设计,其中 C 调用 super,调用 A 代码,后者也调用调用 B 代码的super有关可以使用 super 完成哪些操作的详细信息,请参阅 http://rhettinger.wordpress.com/2011/05/26/super-considered-super

[Response question as later edited ]

因这里,除非我知道/控制init是我从( A 和B ) 继承的类,但是我不能对所编写的类进行安全选择。

引用的文章展示了如何通过在 AB 中添加包装类来处理这种情况。"。如何合并非协作类"一节中有一个worked的例子。

我们可能希望多次继承,让你轻松编写汽车和飞机类,获得一个 FlyingCar,但实际上,我们需要使用适配器或者包装器,因为我们需要的是无缝的组件。

另一种思想:如果你不满意使用多重继承来编写功能,可以以使用组合来完全控制哪些方法。

原作者:
...