Python 2文档说super()函数“返回一个代理对象,它将方法调用委托给父类或兄弟类类型。”
问题:
我的假设是,给定类的兄弟是一个继承自同一父母的类。我起草了以下代码,以了解如何将方法调用委托给兄弟,但它不起作用。我该怎么做或理解错了?
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'
答案 0 :(得分:7)
经过一些进一步的研究和阅读Python’s super() considered super!文章后,我得出了以下结论:
兄弟姐妹课就是我的想法。它是一个继承自同一父级的类。正是Python文档的定义让我不再参与其中。似乎当Python文档说委托对父或兄弟类的方法调用时,它意味着给父母或父母的兄弟,这也是给定孩子的基类。这是钻石继承必须发生的。
super()
函数根据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()
代码将打印
MethodA of ClassB
MethodA of ClassA
如果你像我一样想知道为什么 Class0 的MethodA永远不会被打印出来,这就是我理解的解释。使用print(ClassC.__mro__)
打印的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链进一步调整。
答案 1 :(得分:1)
兄弟姐妹是一个与您怀疑的父母相同的班级。你遗漏的情况是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
在C
,我们调用了super()
,但我们得到了B
- 这是一个兄弟,不是父母而不是兄弟姐妹的父母,但C
的实际直接兄弟。