Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python调用父方法多重继承_Python_Class_Inheritance_Multiple Inheritance - Fatal编程技术网

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
,它有很多技巧,在简单继承和多重继承、混合继承或简单抽象类中都很有用。

如果您不理解我的描述,我想调用all
foo
方法,而不需要在父类中调用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