python类中super()和__init__()的区别


Posted in Python onOctober 18, 2016

单继承时super()和__init__()实现的功能是类似的

class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'creat A ',
Base.__init__(self)
class childB(Base):
def __init__(self):
print 'creat B ',
super(childB, self).__init__()
base = Base()
a = childA()
b = childB()

输出结果:

Base create
creat A Base create
creat B Base create

区别是使用super()继承时不用显式引用基类。

super()只能用于新式类中

把基类改为旧式类,即不继承任何基类

class Base():
def __init__(self):
print 'Base create'

执行时,在初始化b时就会报错:

super(childB, self).__init__()
TypeError: must be type, not classobj

super不是父类,而是继承顺序的下一个类

在多重继承时会涉及继承顺序,super()相当于返回继承顺序的下一个类,而不是父类,类似于这样的功能:

def super(class_name, self):
mro = self.__class__.mro()
return mro[mro.index(class_name) + 1]

mro()用来获得类的继承顺序。

例如:

class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
# Base.__init__(self)
super(childA, self).__init__()
print 'leave A'
class childB(Base):
def __init__(self):
print 'enter B '
# Base.__init__(self)
super(childB, self).__init__()
print 'leave B'
class childC(childA, childB):
pass
c = childC()
print c.__class__.__mro__

输出结果如下:

enter A 
enter B 
Base create
leave B
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

supder和父类没有关联,因此执行顺序是A —> B—>—>Base

执行过程相当于:初始化childC()时,先会去调用childA的构造方法中的 super(childA, self).__init__(), super(childA, self)返回当前类的继承顺序中childA后的一个类childB;然后再执行childB().__init()__,这样顺序执行下去。

在多重继承里,如果把childA()中的 super(childA, self).__init__() 换成Base.__init__(self),在执行时,继承childA后就会直接跳到Base类里,而略过了childB:

enter A 
Base create
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字,

如果是本身就会依次继承下一个类;

如果是继承链里之前的类便会无限递归下去;

如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类;

比如将childA()中的super改为:super(childC, self).init(),程序就会无限递归下去。

如:

File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
RuntimeError: maximum recursion depth exceeded while calling a Python object

super()可以避免重复调用

如果childA基础Base, childB继承childA和Base,如果childB需要调用Base的__init__()方法时,就会导致__init__()被执行两次:

class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
Base.__init__(self)
print 'leave A'
class childB(childA, Base):
def __init__(self):
childA.__init__(self)
Base.__init__(self)
b = childB()

Base的__init__()方法被执行了两次

enter A 
Base create
leave A
Base create

使用super()是可避免重复调用

class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
super(childA, self).__init__()
print 'leave A'
class childB(childA, Base):
def __init__(self):
super(childB, self).__init__()
b = childB()
print b.__class__.mro()
enter A 
Base create
leave A
[<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]

以上所述是小编给大家介绍的python类中super()和__init__()的区别,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python海龟绘图实例教程
Jul 24 Python
web.py 十分钟创建简易博客实现代码
Apr 22 Python
如何在Python函数执行前后增加额外的行为
Oct 20 Python
python实现xlsx文件分析详解
Jan 02 Python
对python numpy数组中冒号的使用方法详解
Apr 17 Python
Python中if elif else及缩进的使用简述
May 31 Python
对python中不同模块(函数、类、变量)的调用详解
Jul 16 Python
关于Python解包知识点总结
May 05 Python
matplotlib.pyplot.matshow 矩阵可视化实例
Jun 16 Python
Pytest如何使用skip跳过执行测试
Aug 13 Python
golang中的空接口使用详解
Mar 30 Python
python_tkinter弹出对话框创建
Mar 20 Python
Python 序列的方法总结
Oct 18 #Python
python 异常处理总结
Oct 18 #Python
python 队列详解及实例代码
Oct 18 #Python
django model去掉unique_together报错的解决方案
Oct 18 #Python
django批量导入xml数据
Oct 16 #Python
python中os模块详解
Oct 14 #Python
python append、extend与insert的区别
Oct 13 #Python
You might like
2019十大人气国漫
2020/03/13 国漫
PHP数组内存耗用太多问题的解决方法
2010/04/05 PHP
php遍历文件夹下的所有文件和子文件夹示例
2014/03/20 PHP
PHP简单判断手机设备的方法
2016/08/23 PHP
PHP实现文件上传下载实例
2016/10/18 PHP
ThinkPHP实现简单登陆功能
2017/04/28 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
Javascript 调试利器 Firebug使用详解六
2009/07/05 Javascript
js 获取中文拼音,Select自动匹配字母获取值的代码
2009/09/23 Javascript
JavaScript 自动完成脚本整理(33个)
2009/10/20 Javascript
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
eclipse导入jquery包后报错的解决方法
2014/02/17 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
js检测输入内容全为空格的方法
2014/05/03 Javascript
jQuery实现返回顶部效果的方法
2015/05/29 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
JS如何在数组指定位置插入元素
2020/03/10 Javascript
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
flask中过滤器的使用详解
2018/08/01 Python
对python cv2批量灰度图片并保存的实例讲解
2018/11/09 Python
python tools实现视频的每一帧提取并保存
2020/03/20 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
2019/08/09 Python
CSS3的RGBA中关于整数和百分比值的转换
2015/08/04 HTML / CSS
如何使用html5与css3完成google涂鸦动画
2012/12/16 HTML / CSS
美国零售商店:Blue&Cream
2017/04/07 全球购物
英国最大的在线奢侈手表零售商:Jura Watches
2018/01/29 全球购物
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
SQL语言面试题
2013/08/27 面试题
送给程序员的20个Java集合面试问题
2014/08/06 面试题
企业指导教师评语
2014/04/28 职场文书
服务承诺口号
2014/05/22 职场文书
迎新春趣味活动方案
2014/08/24 职场文书