深入理解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 相关文章推荐
Python格式化css文件的方法
Mar 10 Python
Python导入txt数据到mysql的方法
Apr 08 Python
python去掉行尾的换行符方法
Jan 04 Python
基于python的图片修复程序(实现水印去除)
Jun 04 Python
pandas DataFrame实现几列数据合并成为新的一列方法
Jun 08 Python
python实现定时提取实时日志程序
Jun 22 Python
Python实用技巧之列表、字典、集合中根据条件筛选数据详解
Jul 11 Python
python三方库之requests的快速上手
Mar 04 Python
python快速排序的实现及运行时间比较
Nov 22 Python
Python面向对象封装操作案例详解 II
Jan 02 Python
使用Python matplotlib作图时,设置横纵坐标轴数值以百分比(%)显示
May 16 Python
Python包管理工具pip的15 个使用小技巧
May 17 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
法压式咖啡之制作法
2021/03/03 冲泡冲煮
WML,Apache,和 PHP 的介绍
2006/10/09 PHP
PHP面向对象之事务脚本模式(详解)
2017/06/07 PHP
PHP fopen中文文件名乱码问题解决方案
2020/10/28 PHP
JavaScript 异步调用框架 (Part 3 - 代码实现)
2009/08/04 Javascript
js的逻辑运算符 ||
2010/05/31 Javascript
JavaScript AOP编程实例
2015/06/16 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
2015/06/23 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
Jquery实现简单的轮播效果(代码管用)
2016/03/14 Javascript
使用three.js 画渐变的直线
2016/06/05 Javascript
iframe中使用jquery进行查找的方法【案例分析】
2016/06/17 Javascript
JavaScript使用readAsDataUrl方法预览图片
2017/05/10 Javascript
jQuery Layer弹出层传值到父页面的实现代码
2017/08/17 jQuery
微信小程序使用Socket的实例
2017/09/19 Javascript
vue组件编写之todolist组件实例详解
2018/01/22 Javascript
详解angular路由高亮之RouterLinkActive
2018/04/28 Javascript
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
解决layui-open关闭自身窗口的问题
2019/09/10 Javascript
Vuex模块化应用实践示例
2020/02/03 Javascript
vue框架中props的typescript用法详解
2020/02/17 Javascript
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
Django高级编程之自定义Field实现多语言
2019/07/02 Python
详解Python中正则匹配TAB及空格的小技巧
2019/07/26 Python
python实现高斯(Gauss)迭代法的例子
2019/11/20 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
CSS3的Flexbox布局的简明入门指南
2016/04/08 HTML / CSS
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
使用html5实现表格实现标题合并的实例代码
2019/05/13 HTML / CSS
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
投标邀请书范文
2014/01/31 职场文书
2015年基层党支部工作总结
2015/05/21 职场文书
无保留意见审计报告
2015/06/05 职场文书
2015年暑假工作总结
2015/07/13 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS