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的Flask框架中验证注册用户的Email的方法
Sep 02 Python
详解在Python程序中解析并修改XML内容的方法
Nov 16 Python
解决Python pandas plot输出图形中显示中文乱码问题
Dec 12 Python
Python3离线安装Requests模块问题
Oct 13 Python
Python监控服务器实用工具psutil使用解析
Dec 19 Python
python虚拟环境模块venv使用及示例
Mar 04 Python
利用python控制Autocad:pyautocad方式
Jun 01 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
Jun 08 Python
Python实战之实现简易的学生选课系统
May 25 Python
Python图片检索之以图搜图
May 31 Python
深入浅析python3 依赖倒置原则(示例代码)
Jul 09 Python
opencv用VS2013调试时用Image Watch插件查看图片
Jul 26 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
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
用PHP+MySQL搭建聊天室功能实例代码
2012/08/20 PHP
如何用php生成扭曲及旋转的验证码图片
2013/06/07 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
2015/08/18 PHP
Visual Studio中的jQuery智能提示设置方法
2010/03/27 Javascript
JavaScript的函数式编程基础指南
2016/03/19 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
基于Bootstrap的后台管理面板 Bootstrap Metro Dashboard
2016/06/17 Javascript
jQuery选择器总结之常用元素查找方法
2016/08/04 Javascript
浅谈jQuery中事情的动态绑定
2017/02/12 Javascript
jQuery的$.extend 浅拷贝与深拷贝
2017/03/08 Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
2017/06/04 Javascript
JS实现判断有效的数独算法示例
2019/02/25 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
mapboxgl区划标签避让不遮盖实现的代码详解
2020/07/01 Javascript
原生JavaScript实现五子棋游戏
2020/11/09 Javascript
[49:56]VG vs Optic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
python使用ddt过程中遇到的问题及解决方案【推荐】
2018/10/29 Python
使用 Supervisor 监控 Python3 进程方式
2019/12/05 Python
如何基于python测量代码运行时间
2019/12/25 Python
python 安装移动复制第三方库操作
2020/07/13 Python
HTML5对手机页面长按会粘贴复制禁用的解决方法
2016/07/19 HTML / CSS
苹果台湾官网:Apple台湾
2019/01/05 全球购物
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
法国在线药房:Shop Pharmacie
2019/11/26 全球购物
Java基础类库面试题
2013/09/04 面试题
百度吧主申请感言
2014/01/12 职场文书
违反校纪校规检讨书
2014/02/15 职场文书
上班迟到检讨书范文300字
2014/11/02 职场文书
2015年复活节活动总结
2015/02/27 职场文书
2015年人力资源部工作总结
2015/04/30 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
2019大学生社会实践报告汇总
2019/08/16 职场文书