python多重继承,调用基类函数
我只是在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
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
属性访问它。