Python调用父方法多重继承
所以,我遇到了这样的情况Python调用父方法多重继承,python,class,inheritance,multiple-inheritance,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
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方法,而不在父类中使用super,如A
。我只想从D
类调用super。A
、B
和C
类与mixin类类似,我想从D
调用所有foo方法。如何实现这一点?在除C
之外的其他类中添加super()
调用。因为D的MRO是
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <type 'object'>)
输出:
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
您可以像这样使用
\uuuuu基
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
我相信在子类中调用super
是一种更具python风格的方法。不必使用父类名称(特别是在super中)。在前一个示例的基础上,下面是一些应该可以工作的代码(python 3.6+):
如果运行此代码:
d = D()
d.foo('D')
您将获得:
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
方法并调用父方法,父方法也会这样做。我们可能在谈论多重继承,但继承树实际上是扁平的(D->A->B->C->Stopfoo->object)。我们可以改变继承顺序,向这个模式添加新类,删除它们,只需调用一个类。。。但是技巧仍然存在:在调用foo
离开我们定义的类之前,包括StopFoo
对于带有钩子的mixin模式,这可能是有意义的。但当然,解决方案也并非在所有情况下都有用。不过,不要害怕super
,它有很多技巧,在简单继承和多重继承、混合继承或简单抽象类中都很有用。如果您不理解我的描述,我想调用allfoo
方法,而不需要在父类中调用super,比如A
或B
或C
@EdwinLunando——我相信事情不是这样的。为了让super正常工作,所有类都需要使用它@EdwinLunando然后遍历\uuuuMRO\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,或者\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。现在,您只能从派生类(也派生自C
(或类似类))中使用这些类,并且顺序也变得很重要(C
必须是最后一个)。要使其正确工作,您需要从实现foo
的基类派生所有类。。。如果现在有两个类都从D继承,然后又有一个类从这两个类继承呢?现在foo
将调用A.foo
两次。或者如果B.foo
不存在会发生什么?最后,我认为应该是cls.foo(self)
,而不是cls().foo()
@mgilson那么,我们必须使用mro
?这些不是类方法,对吗?因此,我必须创建对象来调用它们。它们不是类方法,但是如果显式地将self
作为第一个参数传递(并且self
的类型正确),则可以从类中调用该方法。在这种情况下,self
没有问题,但是在他的实际代码中,他可能会变异自我
,这会产生问题。所以,我认为最好是这样称呼它
foo from D, call from D
foo from A, call from D
foo from B, call from A
foo from C, call from B