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 相关文章推荐
vc6编写python扩展的方法分享
Jan 17 Python
python中os操作文件及文件路径实例汇总
Jan 15 Python
按日期打印Python的Tornado框架中的日志的方法
May 02 Python
Windows下Python2与Python3两个版本共存的方法详解
Feb 12 Python
Pandas DataFrame 取一行数据会得到Series的方法
Nov 10 Python
简单了解django orm中介模型
Jul 30 Python
Win10下python 2.7与python 3.7双环境安装教程图解
Oct 12 Python
python二分法查找算法实现方法【递归与非递归】
Dec 06 Python
Python脚本导出为exe程序的方法
Mar 25 Python
PyTorch-GPU加速实例
Jun 23 Python
python判断字符串以什么结尾的实例方法
Sep 18 Python
如何设置PyCharm中的Python代码模版(推荐)
Nov 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
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
2011/06/24 PHP
PHP CURL获取返回值的方法
2014/05/04 PHP
jQuery+PHP实现的掷色子抽奖游戏实例
2015/01/04 PHP
PHP实现将标点符号正则替换为空格的方法
2017/08/09 PHP
PHP PDOStatement::nextRowset讲解
2019/02/01 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
使用dynatrace-ajax跟踪JavaScript的性能
2010/04/12 Javascript
轻量级 JS ToolTip提示效果
2010/07/20 Javascript
javascript中的一些注意事项 更新中
2010/12/06 Javascript
缓动函数requestAnimationFrame 更好的实现浏览器经动画
2012/12/07 Javascript
JavaScript也谈内存优化
2014/06/06 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
基于Bootstrap的Metronic框架实现条码和二维码的生成及打印处理操作
2016/08/29 Javascript
详解nodejs微信公众号开发——6.自定义菜单
2017/04/13 NodeJs
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
jquery easyui如何实现格式化列
2017/07/30 jQuery
H5+C3+JS实现双人对战五子棋游戏(UI篇)
2020/05/28 Javascript
JavaScript交换变量的常用方法小结【4种方法】
2020/05/07 Javascript
python以环状形式组合排列图片并输出的方法
2015/03/17 Python
python数据结构之线性表的顺序存储结构
2018/09/28 Python
python实现布隆过滤器及原理解析
2019/12/08 Python
使用python实现时间序列白噪声检验方式
2020/06/03 Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
2021/02/25 Python
雅诗兰黛旗下专业男士保养领导品牌:Lab Series
2017/05/15 全球购物
美国沙龙美发产品购物网站:Hair.com by L’Oreal
2020/11/09 全球购物
团代会宣传工作方案
2014/05/08 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
法院干警四风问题个人对照检查材料思想汇报
2014/10/07 职场文书
家长对孩子的寄语
2015/02/26 职场文书
任长霞观后感
2015/06/16 职场文书
经典爱情感言
2015/08/03 职场文书
小学安全教育主题班会
2015/08/12 职场文书
2016年心理学教育培训学习心得体会
2016/01/12 职场文书
MongoDB数据库之添删改查
2022/04/26 MongoDB
Redis配置外网可访问(redis远程连接不上)的方法
2022/12/24 Redis