了解超级工作原理

时间:2014-09-08 11:56:20

标签: python python-2.7

在python程序下面给出。

class FooBase(object):
   def foo(self): pass

class A(FooBase):
    def foo(self):
        super(A, self).foo()
        print 'A.foo()'

class B(FooBase):
    def foo(self):
        super(B, self).foo()
        print 'B.foo()'

class D(B):
    def foo(self):
        super(D, self).foo()
        print 'D.foo()'


class C(A,D,B):
    def foo(self):
        super(C, self).foo()
        print 'C.foo()'

c=C()
c.foo()

输出

B.foo()
D.foo()
A.foo()
C.foo()

但当我跑到节目以下时

class A1(object):
    def get(self):
        print 'A1'
class A2(object):
    def get(self):
        print 'A2'
class A3(object):
    def get(self):
        print 'A3'
class B2(A2):
    def get(self):
        super(B2,self).get()
        print 'b2'
class B3(A3):
    def get(self):
        super(B3,self).get()
        print 'b3'
class C3(B3):
    def get(self):
        super(C3,self).get()
        print 'c3'
class Foo(C3, A1, B2):
    def get(self):
        super(Foo,self).get()
        print 'Foo'



#print Foo.__mro__
Foo().get()

当我执行上述操作时,我得到了如下输出

输出

A3
b3
c3
Foo

为什么A1.get()B2.get()没有被调用的问题。调用超级有什么不对吗?

我期待输出

A3
b3
c3
A1
A2
b2
Foo

编辑:如果有人解释第一个和第二个例子之间的区别会很棒:)

1 个答案:

答案 0 :(得分:2)

您正在定义一个新的样式类,从多个类(multiple inheritance)继承子类。因此,

  

对于旧式课程,唯一的规则是深度优先,从左到右。因此,如果在DerivedClassName中找不到属性,则在Base1中搜索它,然后(递归地)在Base1的基类中搜索,并且只有在那里找不到它时,才会在Base2中搜索它,依此类推。

     

对于新式类,动态排序是必要的,因为所有多重继承的情况都表现出一个或多个菱形关系(其中至少有一个父类可以通过最底层的多个路径访问)。例如,所有新样式类都继承自object,因此任何多重继承的情况都会提供多个到达对象的路径。为了防止基类被多次访问,动态算法以保持每个类中指定的从左到右排序的方式线性化搜索顺序

因此,在线性排序中,只调用C3.get,然后调用B3.get,调用A3.get


如果您还想从其他类中打印get方法,请使用以下Foo类:

class Foo(C3, A1, B2):
    def get(self):
        print '='*20 + 'Foo'
        super(Foo, self).get()
        print '='*20 + 'A1'
        super(A1, self).get()
        print '='*20 + 'B2'
        super(B2, self).get()

然后,运行的代码应该输出正确的文本

$ python file.py 
====================Foo
A3
b3
c3
====================A1
A2
b2
====================B2
A2