深入理解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 isinstance判断对象类型
Sep 06 Python
用python + openpyxl处理excel2007文档思路以及心得
Jul 14 Python
Python实现图片转字符画的示例
Aug 22 Python
Python将多份excel表格整理成一份表格
Jan 03 Python
Python实现matplotlib显示中文的方法详解
Feb 06 Python
Python读写/追加excel文件Demo分享
May 03 Python
深入浅析python 中的匿名函数
May 21 Python
Django配置celery(非djcelery)执行异步任务和定时任务
Jul 16 Python
Python实现的远程文件自动打包并下载功能示例
Jul 12 Python
手动安装python3.6的操作过程详解
Jan 13 Python
python求最大公约数和最小公倍数的简单方法
Feb 13 Python
Python Selenium操作Cookie的实例方法
Feb 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
Access数据库导入Mysql的方法之一
2006/10/09 PHP
默默简单的写了一个模板引擎
2007/01/02 PHP
PHP 危险函数解释 分析
2009/04/22 PHP
使用php将某个目录下面的所有文件罗列出来的方法详解
2013/06/21 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
IE与FireFox中的childNodes区别
2011/10/20 Javascript
javascript对select标签的控制(option选项/select)
2013/01/31 Javascript
JQuery 文本框回车跳到下一个文本框示例代码
2013/08/30 Javascript
使用jQuery实现星级评分代码分享
2014/12/09 Javascript
Bootstrap多级导航栏(级联导航)的实现代码
2016/03/08 Javascript
基于Javascript倒计时效果
2016/12/22 Javascript
微信小程序 九宫格实例代码
2017/01/21 Javascript
AngularJS使用拦截器实现的loading功能完整实例
2017/05/17 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
layui 表单标签的校验方法
2019/09/04 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
2019/10/08 Javascript
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
Python Socket传输文件示例
2017/01/16 Python
python中判断文件编码的chardet(实例讲解)
2017/12/21 Python
redis之django-redis的简单缓存使用
2018/06/07 Python
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
2019/06/25 Python
python读取与处理netcdf数据方式
2020/02/14 Python
python实现拼接图片
2020/03/23 Python
互动出版网:专业书籍
2017/03/21 全球购物
企业宣传工作方案
2014/06/02 职场文书
电子商务专业毕业生自荐书
2014/06/22 职场文书
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
军人离婚协议书样本
2014/10/21 职场文书
成都人事代理协议书
2014/10/25 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
php远程请求CURL案例(爬虫、保存登录状态)
2021/04/01 PHP
Oracle更换为MySQL遇到的问题及解决
2021/05/21 Oracle
浅谈Python数学建模之线性规划
2021/06/23 Python