from https://mozillazg.com/2016/12/python-super-is-not-as-simple-as-you-thought.html# 这个作者真的牛逼
在单继承中 super 就像大家所想的那样,主要是用来调用父类的方法的。
class A: 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
你觉得执行下面代码后, b.n 的值是多少呢?
b = B() b.add(2) print(b.n)
执行结果如下:
self is <__main__.B object at 0x106c49b38> @B.add self is <__main__.B object at 0x106c49b38> @A.add 8
这个结果说明了两个问题:
- super().add(m) 确实调用了父类 A 的 add 方法。
- super().add(m) 调用父类方法 def add(self, m) 时, 此时父类中 self 并不是父类的实例而是子类的实例, 所以b.add(2) 之后的结果是 5 而不是 4 。
不知道这个结果是否和你想到一样呢?下面我们来看一个多继承的例子。
这次我们再定义一个 class C,一个 class D:
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() d.add(2) print(d.n)
这次的输出如下:
self is <__main__.D object at 0x10ce10e48> @D.add self is <__main__.D object at 0x10ce10e48> @B.add self is <__main__.D object at 0x10ce10e48> @C.add self is <__main__.D object at 0x10ce10e48> @A.add 19
你说对了吗?你可能会认为上面代码的输出类似:
self is <__main__.D object at 0x10ce10e48> @D.add self is <__main__.D object at 0x10ce10e48> @B.add self is <__main__.D object at 0x10ce10e48> @A.add 15
为什么会跟预期的不一样呢?下面我们将一起来看看 super 的奥秘。
为什么会跟预期的不一样呢?下面我们将一起来看看 super 的奥秘。
后面太长了,原博太精彩
你不知道的 super \from http://funhacks.net/explore-python/Class/super.html
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super
来实现,比如:
class Animal(object): def __init__(self, name): self.name = name def greet(self): print 'Hello, I am %s.' % self.name class Dog(Animal): def greet(self): super(Dog, self).greet() # Python3 可使用 super().greet() print 'WangWang...'
在上面,Animal 是父类,Dog 是子类,我们在 Dog 类重定义了 greet
方法,为了能同时实现父类的功能,我们又调用了父类的方法,看下面的使用:
>>> dog = Dog('dog') >>> dog.greet() Hello, I am dog. WangWang..
super
的一个最常见用法可以说是在子类中调用父类的初始化方法了,比如:
class Base(object): def __init__(self, a, b): self.a = a self.b = b class A(Base): def __init__(self, a, b, c): super(A, self).__init__(a, b) # Python3 可使用 super().__init__(a, b) self.c = c