写python时经常会用到 super ,在 django 的 cbv 模式中使用的比较频繁,有时候会有点懵,这里为啥要用super啊。 为了解决这个问题所以在网上收集了一些资料

super 用来调用父类的方法, 一般用于多重继承

python 2.7 及以下版本

1
super(className, self).mathod()

python 3.6 及以下版本

1
super().mathod()

单继承比较简单,这里就不写了。多重继承的情况

 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
31
32
33
34
35
36
37
38
39
40
41
42
43

class A(object):
    def __init__(self):
        self.n = 2

    def add(self, m):
        print('self is {0} @A.add'.format(self))
        self.n += m


class B(A):
    def __init__(self):
        self.n = 3

    def add(self, m):
        print('self is {0} @B.add'.format(self))
        super().add(m)
        self.n += 3


class C(A):
    def __init__(self):
        self.n = 4

    def add(self, m):
        print('self is {0} @C.add'.format(self))
        super().add(m)
        self.n += 4


class D(B, C):
    def __init__(self):
        self.n = 5

    def add(self, m):
        print('self is {0} @D.add'.format(self))
        super().add(m)
        self.n += 5

d = D()
print D.mro()
d.add(2)
print(d.n)

将输出:

1
2
3
4
5
6
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
self is <__main__.D object at 0x7f251685aed0> @D.add
self is <__main__.D object at 0x7f251685aed0> @B.add
self is <__main__.D object at 0x7f251685aed0> @C.add
self is <__main__.D object at 0x7f251685aed0> @A.add
19

怎么来的可能有点晕,这里有个概念就mro(Method Resolution Order), 即:方法执行顺序

这个例子中:

1
d.add(2) 的执行顺序[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]

这里头比较有迷惑性的是对象中的n. 最先执行的class A 中的n 是D这个对象中的n:5 add方法只会执行一次, 整个过程过程就是递归

1
2
3
4
5
6
class D(B, C):          class B(A):            class C(A):             class A:
    def add(self, m):       def add(self, m):      def add(self, m):       def add(self, m):
        super().add(m)  1.--->  super().add(m) 2.--->  super().add(m)  3.--->  self.n += m
        self.n += 5   <------6. self.n += 3    <----5. self.n += 4     <----4. <--|
        (14+5=19)               (11+3=14)              (7+4=11)                (5+2=7)

参考资料: