【问题标题】:Regarding python MRO and how super() behaves关于 python MRO 以及 super() 的行为方式
【发布时间】:2013-12-12 14:10:06
【问题描述】:

今天我试图弄清楚 __mro__ 和 super 在 python 中是如何工作的,我发现了一些对我来说既有趣又奇怪的东西,因为我得到了一些我在阅读 __mro__ 后并不理解的东西。这是代码sn-ps。

代码片段 1:

#!/usr/bin/pyhon

class A(object):
    def test(self):
        return 'A'

class B(A):
    def test(self):
        return 'B to %s' % super(B, self).test()

class C(A):
    def test(self):
        return 'C'

class D(B, C):
    pass

print D().test()

输出:

 B to C

代码 sn-p 2:当我在 B 类中更新我的超级时:

#!/usr/bin/pyhon

class A(object):
    def test(self):
        return 'A'

class B(A):
    def test(self):
        return 'B to %s' % super(C, self).test()

class C(A):
    def test(self):
        return 'C'

class D(B, C):
    pass

print D().test()

输出:

B to A

然后现在我得到了我之前的预期。有人可以解释一下 mro 如何与 super 一起工作吗?

【问题讨论】:

  • 我可以发誓一个很好的解释已经是 StackOverflow 搜索“Python super”的第一名,但显然不是。他们都没有真正解释它;最好的结果只是链接到其他网站。
  • 是的,我什至试图从堆栈中的各种超级博客以及谷歌中找出答案。
  • 感谢您的链接,这让我了解了很多我以前不知道的东西:)

标签: python class python-2.7 super method-resolution-order


【解决方案1】:

D 的 MRO 是 [D, B, C, A, object]。

super(C, self)~A

super(B, self)~C

super(MyClass, self) 不是关于“MyClass 的基类”,而是关于 MyClass 的 MRO 列表中的下一个类。

如 cmets 中所述,super(…) 实际上不会返回 MRO 中的下一个类,而是将调用委托给它。

【讨论】:

  • 所以,如果我将class D(B, C): 更改为class D(C, B):,MRO 将更改为D->C->B->A->Object,之后我尝试此return 'B to %s' % super(B, self).test() 仍然得到相同的输出。
  • 不明白。如果您仍然调用D().test(),您只会得到一个C 作为输出。 super(B, self).test() 甚至没有被调用。
  • 糟糕,你说得对,我忘了我还有一个来自 C 类的返回“C”。所以,我想你回答了我的问题。谢谢你。
  • 明确一点,super(C, self) 是一个 super 对象,它将方法调用委托给 MRO 中的下一个对象。正如答案所建议的那样,不是 MRO 中的下一个对象。也就是说,在第一种情况下,super(C, self) is A 将返回 False。
  • 谢谢,我相应地改变了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多