关于python:了解super如何工作

Understanding how super works

本问题已经有最佳答案,请猛点这里访问。

下面给出了python程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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()

输出是

1
2
3
4
B.foo()
D.foo()
A.foo()
C.foo()

但当我低于程序运行时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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()

当我执行上述任务时,得到的输出如下

输出

1
2
3
4
A3
b3
c3
Foo

为什么不叫A1.get()B2.get(),super有什么问题吗?

我在期待产量

1
2
3
4
5
6
7
A3
b3
c3
A1
A2
b2
Foo

编辑:如果有人解释第一个和第二个示例之间的区别,那就太好了:)


您正在定义一个新的样式类,从多个类(多继承)中进行子类化。像这样的,

For old-style classes, the only rule is depth-first, left-to-right. Thus, if an attribute is not found in DerivedClassName, it is searched in Base1, then (recursively) in the base classes of Base1, and only if it is not found there, it is searched in Base2, and so on.

With new-style classes, dynamic ordering is necessary because all cases of multiple inheritance exhibit one or more diamond relationships (where at least one of the parent classes can be accessed through multiple paths from the bottommost class). For example, all new-style classes inherit from object, so any case of multiple inheritance provides more than one path to reach object. To keep the base classes from being accessed more than once, the dynamic algorithm linearizes the search order in a way that preserves the left-to-right ordering specified in each class

因此,在线性排序中,只调用C3.get,依次调用B3.getA3.get

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

1
2
3
4
5
6
7
8
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()

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

1
2
3
4
5
6
7
8
9
10
$ python file.py
====================Foo
A3
b3
c3
====================A1
A2
b2
====================B2
A2