Python调用父方法多重继承

时间:2013-12-08 07:23:07

标签: python class inheritance multiple-inheritance

所以,我有这种情况。

class A(object):
    def foo(self, call_from):
        print "foo from A, call from %s" % call_from


class B(object):
    def foo(self, call_from):
        print "foo from B, call from %s" % call_from


class C(object):
    def foo(self, call_from):
        print "foo from C, call from %s" % call_from


class D(A, B, C):
    def foo(self):
        print "foo from D"
        super(D, self).foo("D")

d = D()
d.foo()

代码的结果是

foo from D
foo from A, call from D

我想在D类中调用所有父方法,在本例中为foo方法,而不在像A这样的父类中使用super。我只想打电话给D班的超级。 ABC类就像mixin类一样,我想从D调用所有foo方法。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:9)

除了super()之外,还可以在其他课程中添加C来电。因为D的MRO是

>>> D.__mro__
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <type 'object'>)

您不需要C中的超级电话。

<强>代码:

class A(object):
    def foo(self, call_from):
        print "foo from A, call from %s" % call_from
        super(A,self).foo('A')

class B(object):
    def foo(self, call_from):
        print "foo from B, call from %s" % call_from
        super(B, self).foo('B')


class C(object):
    def foo(self, call_from):
        print "foo from C, call from %s" % call_from

class D(A, B, C):
    def foo(self):
        print "foo from D"
        super(D, self).foo("D")

d = D()
d.foo()

<强>输出:

foo from D
foo from A, call from D
foo from B, call from A
foo from C, call from B

答案 1 :(得分:8)

您可以像这样使用__bases__

class D(A, B, C):
    def foo(self):
        print "foo from D"
        for cls in D.__bases__:
            cls().foo("D")

通过此更改,输出将为

foo from D
foo from A, call from D
foo from B, call from D
foo from C, call from D

答案 2 :(得分:0)

我相信在子类中对<% if(typeof errors != 'undefined'){ %> <% errors.forEach(function(error) { %> <div class="alert alert-warning alert-dismissible fade show" role="alert"> <%= error.msg %> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <% }); %> 的调用是更Python化的方法。一个人不必使用父类名(尤其是在super中)。在前面的示例中进行详细说明,下面是一些应该起作用的代码(python 3.6 +):

res.render('partial/messages', { errors: errors, layout: false});

如果运行此代码:

 error: function(jqXHR, textStatus, errorThrown){
     $('#errors').append(jqXHR.responseText);
 }

您将获得:

super

此策略的优点是您不必费心继承顺序(包括class A: def foo(self, call_from): print(f"foo from A, call from {call_from}") super().foo('A') class B: def foo(self, call_from): print(f"foo from B, call from {call_from}") super().foo('B') class C(object): def foo(self, call_from): print(f"foo from C, call from {call_from}") super().foo('C') class StopFoo: def foo(self, call_from): pass class D(A, B, C, StopFoo): def foo(self, call_from): print(f"foo from D, call from {call_from}") super().foo('D') 类在内的AS LONG)。这个有点特殊,可能不是完成此任务的最佳策略。基本上,继承树中的每个类都调用d = D() d.foo('D') 方法并调用父方法,其作用相同。我们可能在谈论多重继承,但是继承树实际上是平坦的(D-> A-> B-> C-> Stopfoo-> object)。我们可以更改继承的顺序,向此模式添加新类,删除它们,只调用一个类...但诀窍仍然是:在对foo from D, call from D foo from A, call from D foo from B, call from A foo from C, call from B 的调用离开我们拥有的类之前,先包含StopFoo定义。

对于带有钩子的混合模式,这可能是有道理的。但是,当然,该解决方案也不是在每种情况下都没有用。不过请不要担心foo,它具有许多技巧,并且可以通过mixins或简单的抽象类在简单和多重继承中有用。