深入理解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实现的ini文件操作类分享
Nov 20 Python
python使用urllib2提交http post请求的方法
May 26 Python
Python基于pygame实现的font游戏字体(附源码)
Nov 11 Python
[原创]教女朋友学Python(一)运行环境搭建
Nov 29 Python
浅谈python中真正关闭socket的方法
Dec 18 Python
Python3.5面向对象程序设计之类的继承和多态详解
Apr 24 Python
Python button选取本地图片并显示的实例
Jun 13 Python
Django使用uwsgi部署时的配置以及django日志文件的处理方法
Aug 30 Python
python实现代码统计程序
Sep 19 Python
python 求定积分和不定积分示例
Nov 20 Python
Python unittest 自动识别并执行测试用例方式
Mar 09 Python
python index() 与 rindex() 方法的使用示例详解
Dec 24 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
用Flash图形化数据(一)
2006/10/09 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
javascript 实用的文字链提示框效果
2010/06/30 Javascript
js中的string.format函数代码
2020/08/11 Javascript
nodejs读取memcache示例分享
2014/01/02 NodeJs
javascript实现数字验证码的简单实例
2014/02/10 Javascript
JQuery 使用attr方法实现下拉列表选中
2014/10/13 Javascript
JavaScript中的全局对象介绍
2015/01/01 Javascript
js改变透明度实现轮播图的算法
2020/08/24 Javascript
AngularJS自定义指令详解(有分页插件代码)
2017/06/12 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
2017/07/23 Javascript
详谈Node.js之操作文件系统
2017/08/29 Javascript
JavaScript中关于class的调用方法
2017/11/28 Javascript
nodejs调取微信收货地址的方法
2017/12/20 NodeJs
Vue 事件处理操作实例详解
2019/03/05 Javascript
elementui之el-tebs浏览器卡死的问题和使用报错未注册问题
2019/07/06 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[10:24]郎朗助力完美“圣”典,天籁交织奏响序曲
2016/12/18 DOTA
Python兔子毒药问题实例分析
2015/03/05 Python
python实现文件快照加密保护的方法
2015/06/30 Python
用Eclipse写python程序
2018/02/10 Python
python的dataframe转换为多维矩阵的方法
2018/04/11 Python
Python中__slots__属性介绍与基本使用方法
2018/09/05 Python
python+pyqt5实现图片批量缩放工具
2019/03/18 Python
python 将字符串中的数字相加求和的实现
2019/07/18 Python
HTML5 Web Workers之网站也能多线程的实现
2013/04/24 HTML / CSS
佳能加拿大网上商店:Canon eStore Canada
2018/04/04 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
Lovedrobe官网:英国领先的大码服装品牌
2019/09/19 全球购物
中软国际Java程序员笔试题
2014/07/19 面试题
2015年个人思想总结
2015/03/09 职场文书
AI:如何训练机器学习的模型
2021/04/16 Python
Python音乐爬虫完美绕过反爬
2021/08/30 Python