Python 中的兄弟姐妹 class 是什么?
What is a sibling class in Python?
Python 2 文档说 super() 函数 "returns a proxy object that delegates method calls to a parent or sibling class of type."
问题:
- Python 中的兄弟 class 是什么?
- 如何将方法调用委托给兄弟 class?
我的假设是给定 class 的兄弟姐妹是从同一个 parent 继承的 class。我起草了以下代码以查看如何将方法调用委托给兄弟姐妹,但它没有用。我是怎么做的还是理解错了?
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'
兄弟姐妹是 class 与您所怀疑的相同 parent。你遗漏的情况是 super
可以调用兄弟方法 如果这个 class 本身是从 :
多重继承的
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
——这是一个兄弟,不是一个parent 和 不是 兄弟姐妹的 parent,而是 C
的直接兄弟姐妹。
经过进一步研究和阅读 Python’s super() considered super! 文章,我得出以下结论:
兄弟姐妹 class 是我所想的。它是继承自同一个 parent 的 class。 Python 文档的定义让我偏离了课程。似乎当 Python 文档说 将方法调用委托给 parent 或同级 class 时,这意味着 给 parent 或 parent 的兄弟,它也是给定 child 的基础 class。那是钻石继承必须发生的。
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
如果你和我一样想知道为什么 MethodA of Class0 从未被打印出来,这里是我理解的解释。用 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 链。
Python 2 文档说 super() 函数 "returns a proxy object that delegates method calls to a parent or sibling class of type."
问题:
- Python 中的兄弟 class 是什么?
- 如何将方法调用委托给兄弟 class?
我的假设是给定 class 的兄弟姐妹是从同一个 parent 继承的 class。我起草了以下代码以查看如何将方法调用委托给兄弟姐妹,但它没有用。我是怎么做的还是理解错了?
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'
兄弟姐妹是 class 与您所怀疑的相同 parent。你遗漏的情况是 super
可以调用兄弟方法 如果这个 class 本身是从 :
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
——这是一个兄弟,不是一个parent 和 不是 兄弟姐妹的 parent,而是 C
的直接兄弟姐妹。
经过进一步研究和阅读 Python’s super() considered super! 文章,我得出以下结论:
兄弟姐妹 class 是我所想的。它是继承自同一个 parent 的 class。 Python 文档的定义让我偏离了课程。似乎当 Python 文档说 将方法调用委托给 parent 或同级 class 时,这意味着 给 parent 或 parent 的兄弟,它也是给定 child 的基础 class。那是钻石继承必须发生的。
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
如果你和我一样想知道为什么 MethodA of Class0 从未被打印出来,这里是我理解的解释。用 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 链。