Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.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_Python 2.7_Python 3.x_Inheritance - Fatal编程技术网

python多重继承,调用基类函数

python多重继承,调用基类函数,python,python-2.7,python-3.x,inheritance,Python,Python 2.7,Python 3.x,Inheritance,我只是在python中尝试使用多重继承。我想出了这个 class ParentOne: def foo(self): print("ParentOne foo is called") class ParentTwo: def foo(self): print("ParentTwo foo is called") class Child(ParentOne, ParentTwo): # how is this working d

我只是在python中尝试使用多重继承。我想出了这个

class ParentOne:
    def foo(self):
        print("ParentOne foo is called")

class ParentTwo:
    def foo(self):
        print("ParentTwo foo is called")

class Child(ParentOne, ParentTwo):

    # how is this working
    def call_parent_two_foo(self):
        super(ParentOne, self).foo()

    # This does not work
    def call_parent_foo(self):
        super(ParentTwo, self).foo()

    def call_super_foo(self):
        super(Child, self).foo()

    def foo(self):
        print("Child foo is called")


if __name__ == "__main__":
    child = Child()
    child.foo()
    child.call_super_foo()
    child.call_parent_two_foo()

    # child.call_parent_foo() #This gives the below error
    # super(ParentTwo, self).foo()
    # AttributeError: 'super' object has no attribute 'foo'
它给出以下输出

Child foo is called
ParentOne foo is called
ParentTwo foo is called

我对在本例中如何计算调用
super(ParentOne,self).foo()
感到困惑。根据我的理解,
ParentOne
类不知道
ParentTwo
类的方法和属性。超级如何在多重继承的情况下工作

Python在构建类时构造方法解析顺序(MRO)。MRO始终是线性的。如果python无法创建线性MRO,则会引发
ValueError
。在这种情况下,您的MRO可能如下所示:

Child -> ParentOne -> ParentTwo -> object
现在,当python看到一个
super(cls,self)
时,它基本上会查看
self
并计算出MRO。然后,它使用
cls
确定我们当前在MRO中的位置,最后返回一个对象,该对象将委托给MRO中的下一个类。因此,在这种情况下,
super(Child,self)
调用将返回委托给
ParentOne
的对象。
super(ParentOne,self)
类将返回一个委托给
ParentTwo
的对象。最后,
super(ParentTwo,self)
调用将委托给
对象
。换句话说,您可以将
super
视为以下代码的更高级版本:

def kinda_super(cls, self):
    mro = inspect.getmro(type(self))
    idx = mro.index(cls)
    return Delegate(mro[idx + 1])  # for a suitably defined `Delegate`

请注意,由于
super(ParentTwo,self)
将“委托”返回给
对象
,因此当您尝试
super(ParentTwo,self).foo()
——具体原因是
对象
没有
foo
方法。

您可能理解
子对象(ParentOne,ParentTwo)
作为一个链中的两个独立继承:
Child(ParentOne(ParentTwo))
。实际上,
ParentOne
并不继承
ParentTwo
,它们是两个独立的类,但是方法
super
的工作原理就像有一个继承链一样(仅在多重继承的情况下)。我喜欢这个示例,以便更好地理解发生了什么(对于Python 3.x):

它还考虑两个父类继承一个基类的情况。上面的脚本打印:

P
B
A
C
P
B
A
P
B
举个例子:

y = Y()
要调用基类函数,请执行以下操作:

super(Y,y).run()
super(X1,y).run()
super(X2,y).run()
y.run()
输出

x1
x2
x3
y
x1
x2
x3
y
相似性

super(Y, y).run()
for cls in y.__class__.__bases__:
    if(cls != X3):
        super(cls,y).run()
y.run()
输出

x1
x2
x3
y
x1
x2
x3
y

他们是一种看/得到的方式吗MRO@AnuragSharma--
inspect.getmro
应该给你。IIRC,你也可以通过magic
\uuuuuuuuuuuuuuuuuuu
属性访问它。