深入理解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进阶教程之模块(module)介绍
Aug 30 Python
Python打印scrapy蜘蛛抓取树结构的方法
Apr 08 Python
Python json 错误xx is not JSON serializable解决办法
Mar 15 Python
python字符串与url编码的转换实例
May 10 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
python requests 库请求带有文件参数的接口实例
Jan 03 Python
Python实战购物车项目的实现参考
Feb 20 Python
对python中url参数编码与解码的实例详解
Jul 25 Python
详解mac python+selenium+Chrome 简单案例
Nov 08 Python
python带参数打包exe及调用方式
Dec 21 Python
如何表示python中的相对路径
Jul 08 Python
pycharm配置安装autopep8自动规范代码的实现
Mar 02 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/01 PHP
讲解WordPress中用于获取评论模板和搜索表单的PHP函数
2015/12/28 PHP
实例讲解PHP表单验证功能
2019/02/15 PHP
Js 获取HTML DOM节点元素的方法小结
2009/04/24 Javascript
在IE上直接编辑网页内容的js代码(IE地址栏js)
2009/04/27 Javascript
JavaScript显示当然日期和时间即年月日星期和时间
2013/10/29 Javascript
jQuery Mobile页面返回不需要重新get
2016/04/26 Javascript
JavaScript中闭包的写法和作用详解
2016/06/29 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
详解如何从零开始搭建Express+Vue开发环境
2018/07/17 Javascript
详解Vue CLI3配置解析之css.extract
2018/09/14 Javascript
JavaScript canvas动画实现时钟效果
2020/02/10 Javascript
详解vue 组件注册
2020/11/20 Vue.js
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
2013/11/27 Python
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
python中threading超线程用法实例分析
2015/05/16 Python
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
Python基于百度云文字识别API
2018/12/13 Python
详解python列表(list)的使用技巧及高级操作
2019/08/15 Python
python实现超市管理系统(后台管理)
2019/10/25 Python
Python实现基于socket的udp传输与接收功能详解
2019/11/15 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
python关闭占用端口方式
2019/12/17 Python
Python实现手绘图效果实例分享
2020/07/22 Python
英国排名第一的礼品体验公司:Red Letter Days
2018/08/16 全球购物
小松树教学反思
2014/02/11 职场文书
课程改革实施方案
2014/03/16 职场文书
优秀班组事迹材料
2014/12/24 职场文书
2015年青年志愿者协会工作总结
2015/04/27 职场文书
同学聚会感言一句话
2015/07/30 职场文书
班主任寄语2016
2015/12/04 职场文书
总结Python常用的魔法方法
2021/05/25 Python
Mongo服务重启异常问题的处理方法
2021/07/01 MongoDB
Go获取两个时区的时间差
2022/04/20 Golang
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers