gol*_*lem 11 python oop inheritance super siblings
Python 2 documentation says that super() function "returns a proxy object that delegates method calls to a parent or sibling class of type."
The questions:
我的假设是给定类的兄弟是一个继承自同一父母的类.我起草了以下代码,以了解如何将方法调用委托给兄弟,但它不起作用.我做什么或理解错了什么?
class ClassA(object):
def MethodA(self):
print "MethodA of ClassA"
class ClassB(ClassA):
def MethodB(self):
print "MethodB of ClassB"
class ClassC(ClassA):
def MethodA(self):
super(ClassC, self).MethodA()
def MethodB(self):
super(ClassC, self).MethodB()
if __name__ == '__main__':
ClassC().MethodA() # Works as expected
# Fail while trying to delegate method to a sibling.
ClassC().MethodB() # AttirbuteError: 'super' object has no attribute 'MethodB'
Run Code Online (Sandbox Code Playgroud)
经过一番进一步的研究和阅读,Python的super()被认为超级!文章我得出以下结论:
兄弟姐妹班是我的想法.它是一个继承自同一父级的类.正是Python文档的定义让我不再参与其中.似乎当Python文档说委托方法调用父类或兄弟类时,它意味着父或父的兄弟,它也是给定子的基类.那是钻石继承必须发生的.
super()function 根据MRO(方法解析顺序)自动将方法调用委托给父节点的兄弟类.
这是我在尝试super()函数时发现的一个有趣的案例:
class Class0(object):
def MethodA(self):
print("MethodA of Class0")
class ClassA(Class0):
def MethodA(self):
super(ClassA, self).MethodA()
print("MethodA of ClassA")
class ClassB(Class0):
def MethodA(self):
print("MethodA of ClassB")
class ClassC(ClassA, ClassB):
def MethodA(self):
super(ClassC, self).MethodA()
if __name__ == '__main__':
ClassC().MethodA()
Run Code Online (Sandbox Code Playgroud)
代码将打印出来
MethodA of ClassB
MethodA of ClassA
Run Code Online (Sandbox Code Playgroud)
如果你像我一样想知道为什么Class0的MethodA永远不会被打印出来,这就是我理解的解释.印刷的ClassC的MRO print(ClassC.__mro__)是
(<class '__main__.ClassC'>, <class '__main__.ClassA'>, <class '__main__.ClassB'>, <class '__main__.Class0'>, <class 'object'>).
现在,如果您按照MRO,ClassC的MethodA()的super()函数将调用ClassA的MethodA(),在打印之前将调用classB的MethodA()(因为它是MRO中的下一个).而且,ClassB的MethodA()只会打印并退出,因为它不使用super()函数将方法调用委托给MRO链进一步调用.
正如您所怀疑的,兄弟姐妹是具有同一父级的类。您缺少的情况是,如果此类本身是多重继承的,super则可以调用同级方法:
class A(object):
def something(self):
print("A")
class B(A):
def something(self):
print("B")
class C(A):
def something(self):
print("C, about to call super()")
super(C, self).something()
class D(C, B):
def something(self):
super(D, self).something()
>>> D().something()
C, about to call super()
B
Run Code Online (Sandbox Code Playgroud)
在 中C,我们调用了super(),但我们得到了B- 这是一个兄弟姐妹,不是父母,也不是兄弟姐妹的父母,而是 的实际直接兄弟姐妹C。