Python进阶(七):super()函数
来源:互联网 发布:中国汽车制造业 数据 编辑:程序博客网 时间:2024/05/29 08:16
很早就遇到了这个函数了,一直想写写这个函数的。但又觉得没必要,毕竟这个函数理解起来不难。直到我今天读到一篇文章:听说你会 Python ?有兴趣的可以去看看。
在文章里面提到了一个问题(代码我修改了一下下),就是使用了super()函数,读者们可以试着解解下面这道题:
class Init(object): def __init__(self, x): self.x = xclass Add(Init): def __init__(self, x): super(Add, self).__init__(x) self.x += 2class Mul(Init): def __init__(self, x): super(Mul, self).__init__(x) self.x *= 5class Sub(Mul, Add): def __init__(self, x): super(Sub, self).__init__(x) self.x -= 5class Div(Sub): fsup = super(Sub) def __init__(self, x): self.fsup.__init__(x) self.x /= 5test = Div(5)print(test.x)
答案:7.0
如果这个你解出来了,那么恭喜,这篇文章不用看了。
如果不懂,没关系,跟着我魔鬼的步伐一起来看看这个super()到底是什么鬼东东。
一.继承
这个不用多说,不懂的猛戳这个连接:python的继承
给个例子理解一下:
class A(object): def __init__(self): print("Enter A") print("Exit A")class B(A): def __init__(self): print("Enter B") A.__init__(self) print("Exit B")b = B()
结果如图:
但是上面存在一个问题就是,假如我们修改了A类的名字,比如换成了C。这样我们就需要到子类B去修改A的名字了。上面的例子还好,子类B只需修改两次就OK了。但在实际开发中,项目比较大,有时一个子类要多次调用父类,这么一来,A的名字一旦被修改,那么要到子类B修改A的名字简直就是一个吃力不讨好的活。所以super()函数应运而生。
二.super()函数
上面例子说明了为什么要用super()。好,接下来开始使用super()函数了。
请看下面例子:
class A(object): def __init__(self): print("Enter A") print("Exit A")class B(A): def __init__(self): print("Enter B") super(B, self).__init__() print("Exit B")b = B()
结果和第一个例子一样。但是如果A的名字如过修改。只需在子类修改一次A的名字就好了。
来点有难度的:
class People(object): def __init__(self, name): self.name = name def introduce(self): print("My name is %s!" % self.name)class Student(People): def __init__(self, name, id): super(Student, self).__init__(name) self.id = id def introduce(self): super(Student, self).introduce() print("My ID is %s" % self.id)s = Student('Lifei', 123456)s.introduce()
结果:
这个例子可以比较好的说明为什么要使用super()。如果我们不使用,那么在子类Student中修改People这个类名将要修改三次。如果子类大量调用父类的方法那么一旦需要修改,简直就是噩梦。上面两个例子我们只需修改第一行中的父类名字就可以了
三.深入了解super()
看到这里我们还是无法解决文章开头所提到的问题。
我们来看一个例子:
class A(object): def __init__(self): print("Enter A") print("Exit A")class B(A): def __init__(self): print("Enter B") super(B, self).__init__() print("Exit B")class C(A): def __init__(self): print("Enter C") super(C, self).__init__() print("Exit C")class D(B, C): def __init__(self): print("Enter D") super(D, self).__init__() print("Exit D")d = D()
结果:
这里有个问题就是为什么B类中初始化并不是A,而是跑去初始化C了呢!
凡事都有规范。当然类的继承也是一样的。只不过是通过方法解析顺序(Method Resolution Order, MRO)列表来实现的。这个就是生成了一个顺序列表,至于底层算法怎么样,我们不要去管他。只需知道他帮助我们将类的关系排好了队。
super(cls, type)传入cls类在表中的下一个类。
我们可以执行下以下代码
print(D.mro())
结果
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
所以类的初始化就是按照这个表中的顺序去进行的。当执行到B类时,程序会在B的mro()列表里面寻找到下一个类,然后进入。
**mro遵循的原则:
1.子类永远在父类前面
2.如果有多个父类,会根据它们在列表中的顺序被检查
3. 如果对下一个类存在两个合法的选择,选择第一个父类
当然,super()再调用的时候是可以简写为下面例子的,效果一模一样:
class A(object): def __init__(self): print("Enter A") print("Exit A")class B(A): def __init__(self): print("Enter B") super().__init__() print("Exit B")class C(A): def __init__(self): print("Enter C") super().__init__() print("Exit C")class D(B, C): def __init__(self): print("Enter D") super().__init__() print("Exit D")
博文参考:
python super()
听说你会 Python ?
有问题探讨的请加QQ:1043601529
- Python进阶(七):super()函数
- Python 学习日知录(七)- cmd进阶
- Python super函数
- Python深入:super函数
- Python之super函数
- python-super函数
- Python-理解super函数
- python super()函数
- Python super() 函数
- Python(七)递归函数
- Python进阶-继承中的MRO与super
- 前端基础进阶(七):函数与函数式编程
- python爬虫进阶(七):应对反爬虫的策略
- python中super函数用法
- python的super函数解析
- python的super函数示例
- python 之 super函数学习
- python进阶--内置函数
- 这才是全规格样式车牌识别,秒杀各种“不服”
- 如何在Eclipse下查看JDK源代码以及java源代码阅读方法
- nginx添加lua 业务不中断平滑升级
- 重建二叉树
- CSS
- Python进阶(七):super()函数
- 异或加密的一些认识
- 栈
- sql 处理数据字段为空 如果为空转换成别的值
- UAT SIT QAS DEV PET 的缩写都是什么呀?
- 后台接收json放在list&&mybatis在oracle中批量添加
- C#使用NMS与ActiveMQ通讯问题总结:如何生成Stomp.js中的headers对象
- 沉浸式
- 用 @property 声明的 NSString (或 NSArray,NSDictionary) 经常使用 copy 关键字,为什么?如果改用strong关键字,可能造成什么问题?