深入理解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正则表达式 re模块使用说明
May 19 Python
Python中splitlines()方法的使用简介
May 20 Python
linux平台使用Python制作BT种子并获取BT种子信息的方法
Jan 20 Python
tf.truncated_normal与tf.random_normal的详细用法
Mar 05 Python
python中字符串内置函数的用法总结
Sep 13 Python
python之Flask实现简单登录功能的示例代码
Dec 24 Python
python 实现读取一个excel多个sheet表并合并的方法
Feb 12 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
May 04 Python
python3实现二叉树的遍历与递归算法解析(小结)
Jul 03 Python
使用pytorch完成kaggle猫狗图像识别方式
Jan 10 Python
python中rb含义理解
Jun 18 Python
Keras: model实现固定部分layer,训练部分layer操作
Jun 28 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
Yii2针对游客、用户防范规则和限制的解决方法分析
2016/10/08 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
驱动事件的addEvent.js代码
2007/03/27 Javascript
用js实现随机返回数组的一个元素
2007/08/13 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
JS获取地址栏参数的小例子
2013/08/23 Javascript
JavaScript实现的encode64加密算法实例分析
2015/04/15 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
jquery实现图片上传前本地预览功能
2016/05/10 Javascript
jQuery Tags Input Plugin(添加/删除标签插件)详解
2016/06/20 Javascript
AngularJS入门教程之与服务器(Ajax)交互操作示例【附完整demo源码下载】
2016/11/02 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
jQuery实现文章图片弹出放大效果
2017/04/06 jQuery
使用JQuery实现图片轮播效果的实例(推荐)
2017/10/24 jQuery
vue组件父与子通信详解(一)
2017/11/07 Javascript
JavaScript模拟实现自由落体效果
2018/08/28 Javascript
Angular父子组件通过服务传参的示例方法
2018/10/31 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
15分钟学会vue项目改造成SSR(小白教程)
2019/12/17 Javascript
解决vue初始化项目一直停在downloading template的问题
2020/11/09 Javascript
如何实现vue的tree组件
2020/12/03 Vue.js
Python中用max()方法求最大值的介绍
2015/05/15 Python
解决python opencv无法显示图片的问题
2018/10/28 Python
python3+selenium实现qq邮箱登陆并发送邮件功能
2019/01/23 Python
详解Python 4.0 预计推出的新功能
2019/07/26 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Python IDE环境之 新版Pycharm安装详细教程
2020/03/05 Python
python3.5的包存放的具体路径
2020/08/16 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
建筑工地门卫岗位职责
2014/04/30 职场文书
黄埔军校观后感
2015/06/10 职场文书
干部外出学习心得体会
2016/01/18 职场文书
CSS3 制作的悬停缩放特效
2021/04/13 HTML / CSS
业余无线电通联Q语
2022/02/18 无线电