python3 super().__init__() 和 __init__() 的区别
1、单继承
super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。
class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Create ChildClassA')
super().__init__() ChildClassA()
#输出
#Create ChildClassA
#Create Base
2、多继承
注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。
def GetSupperOrder(class_name,self):
mro = self.__class__.mro()
# #mro()用来获得类的继承顺序。
return mro[mro.index(class_name) + 1] class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Enter ChildClassA')
super().__init__()
print('Leave ChildClassA') class ChildClassB(Base):
def __init__(self):
print('Enter ChildClassB')
super().__init__()
print('Leave ChildClassB') class ChildClassC(ChildClassA,ChildClassB):
pass c = ChildClassC()
print(c.__class__.__mro__)
# 输出:
#Enter ChildClassA
#Enter ChildClassB
#Create Base
#Leave ChildClassB
#Leave ChildClassA
#(<class '__main__.ChildClassC'>, <class '__main__.ChildClassA'>, <class '__main__.ChildClassB'>, <class '__main__.Base'>, <class 'object'>) 从以上结果,可以看出:
super()和父类没有关系,继承执行的顺序是 ChildClassA → ChildClassB → Base → Object 执行过程:
首先初始化ChlidClassC() ,初始化时先调用ChildClassA的构造方法__Init__(),
进而调用super().__init__()方法,此方法返回当前类的继承顺序中ChildClassA后的一个类ChildClassB,然后在执行ChildClassB的构造方法,
最后执行Base的构造方法,然后依次返回,并执行完成。
在多重继承中 ,ChildClassA()中的 super().__init__() 换成Base.__init__(self),在执行时,继承childA后就会直接跳到Base类里,而略过了ChildClassB:
Enter ChildClassA
Create Base
Leave ChildClassA
(<class '__main__.ChildClassC'>, <class '__main__.ChildClassA'>, <class '__main__.ChildClassB'>, <class '__main__.Base'>, <class 'object'>)
从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字,
如果是本身就会依次继承下一个类;
如果是继承链里之前的类便会无限递归下去;
如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类;
比如将ChidClassA()中的super改为:super(ChidClassC, self).__init__(),程序就会无限递归下去。
Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
...
Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
Enter ChildClassA
File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 53, in <module>
c = ChildClassC()
File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
super(ChildClassC, self).__init__()
File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
super(ChildClassC, self).__init__()
File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 41, in __init__
super(ChildClassC, self).__init__()
[Previous line repeated 992 more times]
File "D:/Python20190819/WebApp/venv/Include/testunit.py", line 40, in __init__
print('Enter ChildClassA')
RecursionError: maximum recursion depth exceeded while calling a Python object
3、super()避免重复调用
如果ChildClassA继承Base, ChildClassB继承ChildClassA和Base,如果ChildClassB需要调用Base的__init__()方法时,就会导致__init__()被执行两次:
"""
单继承 super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。 class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Create ChildClassA')
super().__init__() class ChildClassB(Base):
def __init__(self):
print('Create ChildClassB')
super().__init__() ChildClassA()
#输出
#Create ChildClassA
#Create Base
""" """
多继承:
注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。
""" class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Enter ChildClassA')
Base.__init__(self)
print('Leave ChildClassA') class ChildClassB(ChildClassA,Base):
def __init__(self):
print('Enter ChildClassB')
ChildClassA.__init__(self)
Base.__init__(self)
print('Leave ChildClassB') b = ChildClassB() # 输出:
Enter ChildClassB
Enter ChildClassA
Create Base
Leave ChildClassA
Create Base
Leave ChildClassB
supper() 避免重复
"""
单继承 super().__int__()和 Base.__init__(self)是一样的, super()避免了基类的显式调用。 class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Create ChildClassA')
super().__init__() class ChildClassB(Base):
def __init__(self):
print('Create ChildClassB')
super().__init__() ChildClassA()
#输出
#Create ChildClassA
#Create Base
""" """
多继承:
注意:多继承时,会设计继承顺序,supper()相当于返回继承顺序的下一个类,而不是父类。
""" class Base(object):
def __init__(self):
print('Create Base') class ChildClassA(Base):
def __init__(self):
print('Enter ChildClassA')
super( ).__init__()
print('Leave ChildClassA') class ChildClassB(ChildClassA,Base):
def __init__(self):
print('Enter ChildClassB')
super().__init__()
print('Leave ChildClassB') b = ChildClassB() # 输出:
Enter ChildClassB
Enter ChildClassA
Create Base
Leave ChildClassA
Leave ChildClassB
参考自:开源中国 http://my.oschina.net/jhao104/blog/682322
python3 super().__init__() 和 __init__() 的区别的更多相关文章
- python中的__init__和__new__的区别
一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...
- Python中__init__和__new__的区别详解
__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...
- python中的super( test, self).__init__()
python中的super( test, self).__init__() 对继承自父类的属性进行初始化 首先找到test的父类(比如是类A),然后把类test的对象self转换为类A的对象,然后“被 ...
- python3.6 子类的__init__调用父类的__init__
python3.6 子类的__init__调用父类的__init__ 父类 class worker: def __init__(self): self.a=1 self.b=2 if __name_ ...
- super(Student,self).__init__()初始化的是什么东西?
继承不是为了继承里面原来的属性和值么,不初始化的话,会有什么问题? 2015-04-04源自:python进阶 5-17642 浏览2 回答 最佳回答 2015-05-05 1 super(Stude ...
- __init__ 和__new__的区别
__init__和__new__的区别 __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值. __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例, ...
- Python super(Todo,self).__init__() TypeError: super() argument 1 must be type, not classobj
示例如下 class A(): def __init__(self):pass class B(A): def __init__(self): super(A, self).__init__() 当调 ...
- python3 super().__init__()
父类不会自动调用__init__方法 class A: def __init__(self): A = 'A' self.a = 'a' print('init A') class B(A): def ...
- __init__和__new__的区别
根据官方文档: __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值. __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法. 也 ...
随机推荐
- assert函数应用
目录 1 assert概念 2 assert作用 3 assert用法 3.1 检测调用者传过来的指针参数是否正常 3.2 判断某个变量的范围 3.3 assert只检验一个地方 3.4 不能使用改变 ...
- Jupyter notebook部署引导
一.简介方面很多博客写得比较好,主要转发几篇: 1.对Jupyter notebook 的整体进行介绍: https://www.itcodemonkey.com/article/6025.html ...
- Thinkphp 两级联动
<!-- 前端代码部分--><div class="pop-movegroup" id="salesmanBox"> <dl> ...
- 开发神技能 | Python Mock 的入门
Mock是什么 Mock这个词在英语中有模拟的这个意思,因此我们可以猜测出这个库的主要功能是模拟一些东西.准确的说,Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代 ...
- 大数据之路week04--day03(网络编程)
哎,怎么感觉自己变得懒了起来,更新博客的频率变得慢了起来,可能是因为最近得知识开始变得杂变得难了起来,之前在上课的时候,也没有好好听这一方面的知识,所以,现在可以说是在学的新的知识,要先去把新的知识思 ...
- vue 后台获取文件流导出excel文件
let params = { compStartTm: Date.parse(this.searchForm.compStartTm) / 1000, compEndTm: Date.parse(th ...
- 一步一步pwn路由器之wr940栈溢出漏洞分析与利用
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这个是最近爆出来的漏洞,漏洞编号:CVE-2017-13772 固 ...
- nginx中ngx_http_ssl_module模块
此模块为HTTPS提供必要的⽀支持worker_processes auto;http {...server {listen 443 ssl;keepalive_timeout 70;ssl_prot ...
- ajax向后台传递数组参数并将后台响应的数据赋值给一个变量供其它插件使用
1.在js中封装ajax向后台传递数组参数函数 //combogrid * * @Description 封装ajax向后台传递数组参数并将后台响应的数据赋值给一个变量方便其他插件使用该数据函数 * ...
- dp四边形优化
如果dp[i][j]=min(dp[i][k]+dp[k+1][j]+w[i][j]);且满足dp[a][c]+dp[b][d]<=dp[a][d]+dp[c][d](a<b<=c& ...