深入理解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制作爬虫并将抓取结果保存到excel中
Apr 06 Python
Python中 传递值 和 传递引用 的区别解析
Feb 22 Python
python实现log日志的示例代码
Apr 28 Python
python查看列的唯一值方法
Jul 17 Python
python获取微信小程序手机号并绑定遇到的坑
Nov 19 Python
计算机二级python学习教程(3) python语言基本数据类型
May 16 Python
Django中使用 Closure Table 储存无限分级数据
Jun 06 Python
windows 10 设定计划任务自动执行 python 脚本的方法
Sep 11 Python
python字符串的拼接方法总结
Nov 18 Python
Python hashlib常见摘要算法详解
Jan 13 Python
详解Python修复遥感影像条带的两种方式
Feb 23 Python
Python 字典一个键对应多个值的方法
Sep 29 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 中文和编码判断代码
2010/05/16 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
2014/05/06 PHP
详解PHP中的mb_detect_encoding函数使用方法
2015/08/18 PHP
JS解密入门 最终变量劫持
2008/06/25 Javascript
一个JS小玩意 几个属性相加不能超过一个特定值.
2009/09/29 Javascript
Js 代码中,ajax请求地址后加随机数防止浏览器缓存的原因
2013/05/07 Javascript
jQuery 鼠标经过(hover)事件的延时处理示例
2014/04/14 Javascript
自己封装的javascript事件队列函数版
2014/06/12 Javascript
Javascript学习笔记之函数篇(六) : 作用域与命名空间
2014/11/23 Javascript
使表格的标题列可左右拉伸jquery插件封装
2014/11/24 Javascript
纯JavaScript基于notie.js插件实现消息提示特效
2016/01/18 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
2020/12/01 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
使用JS模拟锚点跳转的实例
2018/02/01 Javascript
小程序实现带年月选取效果的日历
2018/06/27 Javascript
vue-cli创建的项目中的gitHooks原理解析
2020/02/14 Javascript
jQuery实现异步上传一个或多个文件
2020/08/17 jQuery
python实现的jpg格式图片修复代码
2015/04/21 Python
在 Python 应用中使用 MongoDB的方法
2017/01/05 Python
使用PyV8在Python爬虫中执行js代码
2017/02/16 Python
matplotlib实现显示伪彩色图像及色度条
2019/12/07 Python
python计算导数并绘图的实例
2020/02/29 Python
Python 数据分析之逐块读取文本的实现
2020/12/14 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
潘多拉意大利官方网上商城:网上选购PANDORA珠宝
2018/10/07 全球购物
函授毕业生的自我鉴定
2013/11/26 职场文书
物业管理毕业生个人的求职信
2013/11/30 职场文书
业务部经理岗位职责
2014/01/04 职场文书
四年级科学教学反思
2014/02/10 职场文书
期终自我鉴定
2014/02/17 职场文书
销售顾问工作计划书
2014/08/15 职场文书
审计局班子四风对照检查材料思想汇报
2014/10/07 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
2015年度员工自我评价范文
2015/03/11 职场文书
房屋维修申请报告
2015/05/18 职场文书
街道办残联2016年助残日活动总结
2016/04/01 职场文书