深入理解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 fileinput模块使用介绍
Nov 30 Python
在Python中操作字典之update()方法的使用
May 22 Python
Python实现的彩票机选器实例
Jun 17 Python
Python实现保证只能运行一个脚本实例
Jun 24 Python
Python安装模块的常见问题及解决方法
Feb 05 Python
python pandas消除空值和空格以及 Nan数据替换方法
Oct 30 Python
python 获取键盘输入,同时有超时的功能示例
Nov 13 Python
python应用文件读取与登录注册功能
Sep 23 Python
python多进程重复加载的解决方式
Dec 13 Python
Python使用enumerate获取迭代元素下标
Feb 03 Python
浅谈Python 参数与变量
Jun 20 Python
如何基于Python pygame实现动画跑马灯
Nov 18 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实时显示输出
2008/10/02 PHP
discuz authcode 经典php加密解密函数解析
2020/07/12 PHP
PHP开发者常犯的10个MySQL错误更正剖析
2012/01/30 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
2015/08/23 PHP
PHP生成条形码大揭秘
2015/09/24 PHP
Symfony2学习笔记之系统路由详解
2016/03/17 PHP
PHP简单验证码功能机制实例详解
2019/03/27 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
PHP+mysql防止SQL注入的方法小结
2019/04/27 PHP
JS 容错处理代码, 屏蔽错误信息
2021/03/09 Javascript
JS与框架页的操作代码
2010/01/17 Javascript
eclipse如何忽略js文件报错(附图)
2013/10/30 Javascript
如何改进javascript代码的性能
2015/04/02 Javascript
JavaScript实现自动变换表格边框颜色
2015/05/08 Javascript
NPM 安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
2016/12/20 Javascript
vue+Java后端进行调试时解决跨域问题的方式
2017/10/19 Javascript
layui框架table 数据表格的方法级渲染详解
2018/08/19 Javascript
vue中多路由表头吸顶实现的几种布局方式
2019/04/12 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
2020/01/19 Javascript
基于vue和websocket的多人在线聊天室
2020/02/01 Javascript
JS使用for in有序获取对象数据
2020/05/19 Javascript
python遍历文件夹,指定遍历深度与忽略目录的方法
2018/07/11 Python
python使用PIL给图片添加文字生成海报示例
2018/08/17 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
解决IDEA 的 plugins 搜不到任何的插件问题
2020/05/04 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
appium+python自动化配置(adk、jdk、node.js)
2020/11/17 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
布里斯班女装时尚品牌:Adrift
2017/12/28 全球购物
static函数与普通函数有什么区别
2015/12/25 面试题
餐厅采购员岗位职责
2014/03/06 职场文书
职务说明书范文
2014/05/07 职场文书
法律意见书范文
2015/05/20 职场文书
2015大学生入党个人自传
2015/06/26 职场文书
优秀范文:读《红岩》有感3篇
2019/10/14 职场文书
Windows和Linux上部署Golang并运行程序
2022/04/22 Servers