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__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法. 也 ...
随机推荐
- CentOS 8 (1905)系统安装
本章内容: CentOS 8 的安装(CentOS-8-1905) 一.安装光盘,选择Install CentOS Linux 8.0.1905 二.选择系统语言,我这里选的是英文,也可以选择中文,往 ...
- FreeRTOS列表和列表项
FreeRTOS中的列表和列表项类似于数据结构中的链表和节点: 相关的文件是list.c和list.h两个文件: List_t列表结构体 具体定义如下: /* * Definition of the ...
- 用js刷剑指offer(二维数组中的查找)
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- 云服务器搭建Jupyter-主要部分为配置服务器安全组
最近在腾讯上租了一个服务器,在CSDN上看到了一个在服务器上搭建Jupyter的帖子,就跟着介绍做了一下. 参考CSDN帖子链接:https://blog.csdn.net/ds19991999/ar ...
- zznu-oj-2117 : 我已经在路上了(求函数的原函数的字符串)--【暴力模拟题,花式模拟题,String大法好】
2117 : 我已经在路上了 时间限制:1 Sec 内存限制:256 MiB提交:39 答案正确:8 提交 状态 编辑 讨论区 题目描述 spring是不折不扣的学霸,那可是机房考研中的头号选手,不吹 ...
- Pycharm----设置默认脚本请求头
每次新建py文件,均需要在文件头部加上编码声明,每次的手动添加比较麻烦,因此设置自动生成,也可添加作者.时间等等,详见如下: 设置后的样例显示: 操作方式: 操作完如上的截图步骤,再次新建一个py文件 ...
- 关于EMF中从schema到ecore转变中的默认处理问题
以前的工作,建模基本都是通过ecore tool直接画ecore的模型图来完成,最近要从schema创建ecore文件,本来以为是非常简单的一件事情,使用向导创建genmodel,然后从xsd文件导入 ...
- Pandas to_sql TypeError: sequence item 0: expected str instance, dict found
问题介绍 打印了一下数据格式,并未发现问题.如果说是字典实例引起的. 我猜测也是extra字段引起的,因为extra字段是一个json字段.根据网上的提示要对这样的格式进行强转str. 其他发现:pd ...
- session.getdefaultinstance和getinstance的区别
如果想要同时使用两个帐号发送javamail,比如使用1@a.com发送1#邮件,使用2@a.com发送2#邮件,这时候,你就需要同时创建两个java.mail.Session对象.但是如果你仍然使用 ...
- webservice的优缺点
优点: 1.采用xml支持跨平台远程调用. 2.基于http的soap协议,可跨越防火墙 3.支持面向对象开发 4.有利于软件和数据的重用,实现松耦合. 缺点: 1.由于soap是基于xml传输,本身 ...