深入理解Python中的super()方法


Posted in Python onNovember 20, 2017

前言

python的类分别有新式类和经典类,都支持多继承。在类的继承中,如果你想要重写父类的方法而不是覆盖的父类方法,这个时候我们可以使用super()方法来实现

python语言与C++有相似的类继承,在类定义时,python中会自定义第一个self,类似C++中this指针,指向对象自身。

python简单的类举例:

>>> class hello(object): 
...     def print_c(): 
...       print"hello world!" 
>>> hello().print_c() 
hello world!

当然在实际中不可避免的需要类的继承,子类继承父类,正常如下:

>>> class child(hello): 
...     def print_c(self): 
...         hello().print_c() 
...          
>>> child().print_c() 
hello world!

在python中还提供了super()机制,例子如下:

>>> class hello(object): 
...     def print_c(self): 
...       print"hello world!" 
...        
>>> class child(hello): 
...     def print_c(self): 
...         super(child,self).print_c() 
...          
>>> child().print_c() 
hello world!

注意

Python2.2以前的版本:经典类(classic class)时代

经典类是一种没有继承的类,实例类型都是type类型,如果经典类被作为父类,子类调用父类的构造函数时会返回这样的错误 '''TypeError: must be type, not classobj'''

这时MRO的方法为DFS(深度优先搜索(子节点顺序:从左到右))。所以本文中使用的是新式类,而新式类的搜索算法是C3算法

class C(object):
 def minus(self,x):
  return x/2

class D(C):
 def minus(self,x):
  super(D, self).minus()
  print 'hello'

上面的代码中C是父类,D是子类,我们在D类重新定义了minus方法,就是在C类的功能基础基础上新添print 'hello'功能。super在这里的作用就是在子类中调用父类的方法,这个也是在单继承常见调用super()的用法。那么问题来了

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

 def minus(self, m):
  self.n -= m


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

 def minus(self, m):
  super(B,self).minus(m)
  self.n -= 2
b=B()
b.minus(2)
print b.n

那么上面的代码中b.n的输出是什么呢?为什么结果是2呢,而不是5呢?super(B,self).minus(m)明明是调用了父类的minus方法,可是输出结果就是2,是你要明白现在B的实例,而不是A的实例,那么传递的self.n的数值是7,而不是10.

那么对于多继承的时候,super又是怎样工作的呢?来,现在创建一个继承A的C类,然后再创建一个继承B,C的D类,看看怎样调用super是重写方法。

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

 def minus(self, m):
  super(C,self).minus(m)
  self.n -= 5


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

 def minus(self, m):
  super(D,self).minus(m)
  self.n -= 2

d=D()
d.minus(2)
print d.n

如上的代码输出的结果是什么呢?别心急,先看看它是怎样运行的。上面提及到新式类寻找子节点时候使用的是C3算法。那么它是怎么找呢。D->B->C->A->object。怎样才能验证这个顺序是对的呢。

D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

Mro是什么呢?对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
2款Python内存检测工具介绍和使用方法
Jun 01 Python
如何使用python爬取csdn博客访问量
Feb 14 Python
python字符串过滤性能比较5种方法
Jun 22 Python
Python使用functools实现注解同步方法
Feb 06 Python
python批量设置多个Excel文件页眉页脚的脚本
Mar 14 Python
Python骚操作之动态定义函数
Mar 26 Python
Python发展史及网络爬虫
Jun 19 Python
python实现翻转棋游戏(othello)
Jul 29 Python
docker django无法访问redis容器的解决方法
Aug 21 Python
Python使用指定字符长度切分数据示例
Dec 05 Python
对pytorch的函数中的group参数的作用介绍
Feb 18 Python
LeetCode189轮转数组python示例
Aug 05 Python
python实现读取excel写入mysql的小工具详解
Nov 20 #Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
Nov 20 #Python
python Matplotlib画图之调整字体大小的示例
Nov 20 #Python
python cx_Oracle的基础使用方法(连接和增删改查)
Nov 19 #Python
Python实现mysql数据库更新表数据接口的功能
Nov 19 #Python
python中urlparse模块介绍与使用示例
Nov 19 #Python
Python Flask-web表单使用详解
Nov 18 #Python
You might like
PHP 处理图片的类实现代码
2009/10/23 PHP
基于simple_html_dom的使用小结
2013/07/01 PHP
php微信公众号开发之答题连闯三关
2018/10/20 PHP
php常用字符串查找函数strstr()与strpos()实例分析
2019/06/21 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
登陆成功后自动计算秒数执行跳转
2014/01/23 Javascript
标题过长使用javascript按字节截取字符串
2014/04/24 Javascript
jquery和js实现对div的隐藏和显示方法
2014/09/26 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
完美的js图片轮换效果
2017/02/05 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
jQuery插件HighCharts绘制2D金字塔图效果示例【附demo源码下载】
2017/03/09 Javascript
Vue中v-show添加表达式的问题(判断是否显示)
2018/03/26 Javascript
vue 实现axios拦截、页面跳转和token 验证
2018/07/17 Javascript
Vue 组件参数校验与非props特性的方法
2019/02/12 Javascript
Three.js中矩阵和向量的使用教程
2019/03/19 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
python正则表达式抓取成语网站
2013/11/20 Python
python中数据爬虫requests库使用方法详解
2018/02/11 Python
Python实现在某个数组中查找一个值的算法示例
2018/06/27 Python
flask-socketio实现WebSocket的方法
2018/07/31 Python
Numpy之文件存取的示例代码
2018/08/03 Python
python使用mitmproxy抓取浏览器请求的方法
2019/07/02 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
python爬虫数据保存到mongoDB的实例方法
2020/07/28 Python
Pycharm 解决自动格式化冲突的设置操作
2021/01/15 Python
CSS3实现闪烁动画效果的方法
2015/02/09 HTML / CSS
HTML5的结构和语义(2):结构
2008/10/17 HTML / CSS
泰国折扣酒店预订:Hotels2Thailand
2018/03/20 全球购物
全球性的在线婚纱礼服工厂:27dress.com
2019/03/21 全球购物
高中毕业的自我鉴定
2013/12/09 职场文书
领导干部贪图享乐整改措施
2014/09/21 职场文书
PHP实现rar解压读取扩展包小结
2021/06/03 PHP
PostgreSQL事务回卷实战案例详析
2022/03/25 PostgreSQL