合作多重继承问题

2024-06-23 19:15:35 发布

您现在位置:Python中文网/ 问答频道 /正文

这是对this question的扩展,并引发了一个问题,我的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's post时,class A的代码应该修改为同时调用super().__init__()

^{pr2}$

到目前为止我们都很好。但是,如果我们的类__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,这与{}错误。然而,删除其中一个super().__init__函数意味着在多重继承的情况下,这些类不再协作。在

在这之后,我的问题是如何解决这个问题?除了没有参数传递给__init__函数的情况外,多重继承似乎被破坏了。在

更新:

Rob在评论中建议去掉关键字参数(在raymondh的帖子中引用)。这实际上在多重继承的情况下非常有效,直到您对代码进行更改。如果某个函数不再使用某个关键字参数,并且在不修改调用函数的情况下停止删除该参数,则仍然会收到上面提到的TypeError。因此,对于大型项目来说,这似乎是一个脆弱的解决方案。在


Tags: 函数代码self参数objectfooinitdef
2条回答

诚然,此解决方案可能不是最具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之后执行。在

测试代码

"""
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()

输出

^{pr2}$

相关问题 更多 >

    热门问题