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中的类与实例
Apr 27 Python
python中迭代器(iterator)用法实例分析
Apr 29 Python
Python使用xlrd模块操作Excel数据导入的方法
May 26 Python
Selenium chrome配置代理Python版的方法
Nov 29 Python
python中数组和矩阵乘法及使用总结(推荐)
May 18 Python
Django实现基于类的分页功能
Oct 31 Python
python创建子类的方法分析
Nov 28 Python
解决pycharm上的jupyter notebook端口被占用问题
Dec 17 Python
PyQt5 文本输入框自动补全QLineEdit的实现示例
May 13 Python
基于Tensorflow读取MNIST数据集时网络超时的解决方式
Jun 22 Python
python实现简单贪吃蛇游戏
Sep 29 Python
python包的导入方式总结
Mar 02 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
PHP fprintf()函数用法讲解
2019/02/16 PHP
Laravel 5.5 异常处理 &amp; 错误日志的解决
2019/10/17 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
php pdo连接数据库操作示例
2019/11/18 PHP
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
jquery Moblie入门—hello world的示例代码学习
2013/01/08 Javascript
Jquery实现页面加载时弹出对话框代码
2013/04/19 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
JavaScript变量声明详解
2014/11/27 Javascript
bootstrap datetimepicker2.3.11时间插件使用
2016/11/19 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
Node.js websocket使用socket.io库实现实时聊天室
2017/02/20 Javascript
vue.js利用Object.defineProperty实现双向绑定
2017/03/09 Javascript
微信小程序 Buffer缓冲区的详解
2017/07/06 Javascript
使用Webpack提高Vue.js应用的方式汇总(四种)
2017/07/10 Javascript
Vue 拦截器对token过期处理方法
2018/01/23 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
vue打包npm run build时候界面报错的解决
2020/08/13 Javascript
python抓取网页内容示例分享
2014/02/24 Python
Python使用functools实现注解同步方法
2018/02/06 Python
Python sorted函数详解(高级篇)
2018/09/18 Python
python装饰器常见使用方法分析
2019/06/26 Python
巧用CSS3的calc()宽度计算做响应模式布局的方法
2018/03/22 HTML / CSS
美国高街时尚品牌:OASAP
2016/07/24 全球购物
美国旅游网站:Tours4Fun
2017/02/17 全球购物
成人大专自我鉴定范文
2013/10/19 职场文书
大学生志愿者感言
2014/01/15 职场文书
社区党员先进事迹
2014/01/22 职场文书
2014年教师节寄语
2014/04/03 职场文书
党员教师个人对照检查材料(群众路线)
2014/09/26 职场文书
自我评价优缺点范文
2015/03/11 职场文书
2015年高三教学工作总结
2015/07/21 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL
Spring整合Mybatis的全过程
2021/06/28 Java/Android
MySQL利用UNION连接2个查询排序失效详解
2021/11/20 MySQL