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编辑器WingIDE的使用经验总结
Aug 31 Python
Python模拟用户登录验证
Sep 11 Python
Python基于time模块求程序运行时间的方法
Sep 18 Python
Python+matplotlib+numpy绘制精美的条形统计图
Jan 02 Python
python实现按长宽比缩放图片
Jun 07 Python
python3 实现对图片进行局部切割的方法
Dec 05 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
Dec 05 Python
Python实现 版本号对比功能的实例代码
Apr 18 Python
Python 操作 MySQL数据库
Sep 18 Python
Python虚拟环境virtualenv创建及使用过程图解
Dec 08 Python
python的dict判断key是否存在的方法
Dec 09 Python
Python实战之实现简易的学生选课系统
May 25 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
老机欣赏|中国60年代精品收音机
2021/03/02 无线电
浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)
2013/06/29 PHP
微信公众号开发之文本消息自动回复php代码
2016/08/08 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
nodejs开发微博实例
2015/03/25 NodeJs
JavaScript计划任务后台运行的方法
2015/12/18 Javascript
JavaScript实现输入框(密码框)出现提示语
2016/01/12 Javascript
JS根据浏览器窗口大小实时动态改变网页文字大小的方法
2016/02/25 Javascript
js实现百度登录框鼠标拖拽效果
2017/03/07 Javascript
微信小程序 实现列表项滑动显示删除按钮的功能
2017/04/13 Javascript
vue 粒子特效的示例代码
2017/09/19 Javascript
layui 表格的属性的显示转换方法
2018/08/14 Javascript
Vue中的作用域CSS和CSS模块的区别
2018/10/09 Javascript
angular 用Observable实现异步调用的方法
2018/12/27 Javascript
详解Vue基于vue-quill-editor富文本编辑器使用心得
2019/01/03 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
[51:15]完美世界DOTA2联赛PWL S2 PXG vs Magma 第一场 11.21
2020/11/24 DOTA
Python编写百度贴吧的简单爬虫
2015/04/02 Python
python 对dataframe下面的值进行大规模赋值方法
2018/06/09 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
jupyter notebook的安装与使用详解
2020/05/18 Python
cookies应对python反爬虫知识点详解
2020/11/25 Python
python爬虫泛滥的解决方法详解
2020/11/25 Python
Mistine官方海外旗舰店:泰国国民彩妆品牌
2016/12/28 全球购物
琳达·法罗眼镜英国官网:Linda Farrow英国
2021/01/19 全球购物
丑小鸭教学反思
2014/02/03 职场文书
中文专业学生自我评价范文
2014/02/06 职场文书
社团活动总结
2014/04/28 职场文书
三月学雷锋活动总结
2014/06/26 职场文书
学校教研活动总结
2014/07/02 职场文书
组工干部演讲稿
2014/09/02 职场文书
2014年学校法制宣传日活动总结
2014/11/01 职场文书
老公写给老婆的检讨书
2015/05/06 职场文书
和谐拯救危机观后感
2015/06/15 职场文书
幼儿园庆元旦主持词
2015/07/06 职场文书
国庆放假通知怎么写
2015/07/30 职场文书