python 2.7 中super()没有按照mro的顺序打印

python 2.7 测试super()的mro顺序,没有按照mro的顺序打印。

代码如下:

# coding:utf-8
__metaclass__ = type

class A(object):
    def __init__(self):
        print "enter A"
        print "leave A"

class B(object):
    def __init__(self):
        print "enter B"
        print "leave B"

class C(A):
    def __init__(self):
        print "enter C"
        super(C,self).__init__()
        print "leave C"

class E(B,C):
    def __init__(self):
        print "enter E"
        super(E,self).__init__()
        print "leave E"

f = E()

期望结果:

enter E
enter B
enter C
……
leave C
leave B
leave E

实际结果:

clipboard.png

mro的顺序:

clipboard.png

为何没有调用类C ?

阅读 2.9k
2 个回答

没有调用C,是因为按照mro(方法解析顺序)顺序调用的时候,解析到B的时候,无法获取到mro列表的下一个元素,因为只有在使用super(cls,self)时,python会在self的mro列表里搜索下一个类。而你的B中根本没有调用super(*)。你改成下面这样运行看看,你会发现self无论在哪里永远是E的实例对象,而且mro列表都是一样。只有每一次调用super才会查找当前self实例mro列表的下一个类。所以在B中加上super(B, self).__init__()就可以获取到mro列表的下一个类,继而可以继续执行父类的方法

class A(object):
    def __init__(self):
        print(type(self))
        print(self.__class__.__mro__)
        print "enter A"
        print "leave A"

class B(object):
    def __init__(self):
        print "enter B"
        print(type(self))
        print(self.__class__.__mro__)
        super(B, self).__init__()
        print "leave B"

class C(A):
    def __init__(self):
        print "enter C"
        print(type(self))
        super(C,self).__init__()
        print(self.__class__.__mro__)

        print "leave C"

class E(B,C):
    def __init__(self):
        print "enter E"
        print(self.__class__.__mro__)
        super(E,self).__init__()
        print "leave E"

f = E()

因为 B.__init__ 就是 super(E,self).__init__() 实际调用的方法。

如果想达到你想要的效果,需要在 B.__init__ 里调用 superC.__init__:

class B(object):
    def __init__(self):
        print "enter B"
        super(B, self).__init__()
        print "leave B"
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题