这是这个问题的扩展,并提出了一个问题,你,我的同胞StackOverflowers,希望能够帮助我。根据引用的问题,考虑最后的代码示例:
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"
如上所述,在初始化C时,永远不会调用B的__init__
。考虑到Raymond Hettinger的帖子,class A
的代码应该修改为也调用super().__init__()
:
class A(object):
def __init__(self):
print "entering A"
super(A, self).__init__()
print "leaving A"
到目前为止我们都很好。但是,如果我们类的__init__
函数接受参数呢?让我们假设所有的__init__
函数都接受一个参数,为了一致性,我们将其简单地称为foo
,现在的代码是:
class A(object):
def __init__(self, foo):
print "entering A"
super(A, self).__init__(foo)
print "leaving A"
class B(object):
def __init__(self, foo):
print "entering B"
super(B, self).__init__(foo)
print "leaving B"
class C(A,B):
def __init__(self, foo):
print "entering c"
super(C, self).__init__(foo)
print "leaving c"
这里我们遇到了一个障碍。当初始化任何类A、B或C时,我们最终调用object.__init__
时只带一个参数foo
,这与TypeError: object.__init__() takes no parameters
错误。然而,删除其中一个super().__init__
函数将意味着在多重继承的情况下,这些类不再具有协作性。
在所有这些之后,我的问题是如何解决这个问题?除了没有向__init__
函数传递参数的情况外,多重继承似乎在任何情况下都被破坏。
更新:
Rob在评论中建议剥离关键字参数(参考Raymond H的帖子)。在您更改代码之前,这实际上在多重继承的情况下工作得非常好。如果你的一个函数不再使用其中一个关键字参数,并且在不修改调用函数的情况下停止剥离它,你仍然会收到上面提到的TypeError。因此,对于大型项目来说,这似乎是一个脆弱的解决方案。
不可否认,这种解决方案可能不是最python化或最理想的,但是为这样的对象创建一个包装器类允许您在继承中的每个__init__
周围传递参数:
class Object(object):
def __init__(self,*args,**kwargs):
super(Object,self).__init__()
class A(Object):
def __init__(self,*args,**kwargs):
super(A,self).__init__(*args,**kwargs)
class B(Object):
def __init__(self,*args,**kwargs):
super(B,self).__init__(*args,**kwargs)
class C(A,B):
def __init__(self,*args,**kwargs):
super(C,self).__init__(*args,**kwargs)
我的答案可能有点偏差。我一直在寻找代码来解决我的特殊问题。但找了几个小时后,我找不到一个好的例子。所以我写了这个小测试代码。我认为这绝对是一个合作多重继承的例子。我真的觉得有人会觉得有用。所以我们开始吧!
基本上,我有一个非常大的类,我想进一步拆分,但由于我的特殊情况,它必须是同一个类。而且我所有的子类都有自己的init,我想在base init之后执行。
<<p> 测试代码/strong>"""
Testing MRO Functionality of python 2.6 (2.7)
"""
class Base(object):
def __init__(self, base_arg, **kwargs):
print "Base Init with arg: ", str(base_arg)
super(Base, self).__init__()
def base_method1(self):
print "Base Method 1"
def base_method2(self):
print "Base Method 2"
class ChildA(Base):
def __init__(self, child_a_arg, **kwargs):
super(ChildA, self).__init__(**kwargs)
print "Child A init with arg: ", str(child_a_arg)
def base_method1(self):
print "Base Method 1 overwritten by Child A"
class ChildB(Base):
def __init__(self, child_b_arg, **kwargs):
super(ChildB, self).__init__(**kwargs)
print "Child B init with arg: ", str(child_b_arg)
def base_method2(self):
print "Base Method 2 overwritten by Child B"
class ChildC(Base):
def __init__(self, child_c_arg, **kwargs):
super(ChildC, self).__init__(**kwargs)
print "Child C init with arg: ", str(child_c_arg)
def base_method2(self):
print "Base Method 2 overwritten by Child C"
class Composite(ChildA, ChildB, ChildC):
def __init__(self):
super(Composite, self).__init__(base_arg=1, child_a_arg=2, child_b_arg=3, child_c_arg=4)
print "Congrats! Init is complete!"
if __name__ == '__main__':
print "MRO: ", str(Composite.__mro__), "n"
print "*** Init Test ***"
test = Composite()
print "*** Base Method 1 Test ***"
test.base_method1()
print "*** Base Method 2 Test ***"
test.base_method2()
MRO: (<class '__main__.Composite'>,
<class '__main__.ChildA'>,
<class '__main__.ChildB'>,
<class '__main__.ChildC'>,
<class '__main__.Base'>,
<type 'object'>)
*** Init Test ***
Base Init with arg: 1
Child C init with arg: 4
Child B init with arg: 3
Child A init with arg: 2
Congrats! Init is complete!
*** Base Method 1 Test ***
Base Method 1 overwritten by Child A
*** Base Method 2 Test ***
Base Method 2 overwritten by Child B