细探Python super()
Posted bug404
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了细探Python super()相关的知识,希望对你有一定的参考价值。
环境
默认以Python3为例,py2,3一些区别如下:
class的定义
Python3
class A:
def __init__(self):
pass
python2
class A(object):
def __init__(self):
pass
super()的调用
python3
class B(A):
def __init__(self):
super().__init__()
pass
python2
class B(A):
def __init__(self):
super(B,self).__init__()
pass
单继承
这是我们平时见到的最多的情况,一个类继承自另一个类。我们用一个小例子简单说明:
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=B()
b.add(2)
print(b.n)
可以先算一下最后结果是多少,然后运行一下程序。
从结果看出,计算流程为:
B: self.n = 3 ---> A: self.n + 2 = 5 ---> B: self.n = self.n + 3 = 5 + 3 = 8
多继承
多继承就比较有意思了。
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
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)
强烈建议自己先算一下。
程序的最终输出为:
程序执行的时候,调用到B类的时候,并没有去调用A类,而是接着去调用C类的add方法,最后调用的A类的add方法。
我们来探究一下super究竟做了什么。
探究super
super是一个类,我们调用super()的时候,实际上是实例化了一个super类。
class A: pass
s=super(A)
type(s)
#output is <class super>
大多数情况下,super包含了两个非常重要的信息:
- MRO(Method Resolution Order)列表
- MRO的一个类
再来看多继承中的例子。
d=D()
d.add(2)
print(d.n)
在python console,我们输入D.mro()
,对于Python2,是D.__mro__
,返回信息为:
[<class __main__.D>, <class __main__.B>, <class __main__.C>, <class __main__.A>, <class object>]
可以看到D的MRO是 [D, B, C, A, object],中途调用B的方法的时候并不会去调用B的父类A的方法,而是按照MRO的顺序去调用C的方法。
参考
https://mozillazg.com/2016/12/python-super-is-not-as-simple-as-you-thought.html
以上是关于细探Python super()的主要内容,如果未能解决你的问题,请参考以下文章