【转】python类中super()和__init__()的区别
【转】python类中super()和__init__()的区别
单继承时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类中super()和__init__()的区别
class Base(object): def __init__(self): print 'Base create' class childB(Base): def __init__(sel ...
- Python类中super()和__init__()的关系
Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...
- 【转】python---方法解析顺序MRO(Method Resolution Order)<以及解决类中super方法>
[转]python---方法解析顺序MRO(Method Resolution Order)<以及解决类中super方法> MRO了解: 对于支持继承的编程语言来说,其方法(属性)可能定义 ...
- 第7.14节 Python类中的实例方法详析
第7.14节 Python类中的实例方法详析 一. 实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1. 类体中定义实例方法 第一种方式很简单,就是在类体 ...
- 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...
- Python 简明教程 --- 20,Python 类中的属性与方法
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 与客户保持良好的关系可以使生产率加倍. -- Larry Bernstain 目录 类中的变量称为属 ...
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
- 第8.12节 Python类中使用__dict__定义实例变量和方法
上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...
随机推荐
- bzoj3991 LCA + set
https://www.lydsy.com/JudgeOnline/problem.php?id=3991 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有 ...
- python对象继承
继承允许我们在两个或者更多的类之间创建一种“是一个”的关系,这种关系把共同的细节抽象到一个超类里. 从技术上讲,每一个我们创建的类都使用了继承,所有的python类都是一个叫做object的特殊类的子 ...
- kaggle竞赛入门整理
1.Bike Sharing Demand kaggle: https://www.kaggle.com/c/bike-sharing-demand 目的:根据日期.时间.天气.温度等特征,预测自行车 ...
- 用go实现一个redis-cli
转载文章:https://my.oschina.net/liangwt/blog/2231557?origin= 代码样例:https://github.com/liangwt/redis-cli
- Yearning 介绍(SQL审核平台)
介绍 Yearning SQL 审计平台 基于Vue.js与Django的整套mysql-sql审核平台解决方案.提供基于Inception的SQL检测及执行. GitHub:https://gith ...
- SQL语法基础之ALTER语句
SQL语法基础之ALTER语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看ALTER的帮助信息 mysql> ? ALTER Many help items fo ...
- Hbase学习01
1.1 快速介绍 1.1.1 快速入门,单节点Hbase 本小节介绍单节点独立HBase的设置. 独立实例包含所有HBase守护进程 - Master,RegionServers和ZooKeeper ...
- Java 读取propertoes文件
我一直不懂,Java里面的路径是咋样的,怎么找到我的资源文件? 直到我看到了这篇文件,写的是真棒.这篇文章 看完之后,豁然开朗的感觉 下面做些笔记,首先,Java有一个targer文件,下面有一个c ...
- js实现table用鼠标改变td的宽度,固定table宽度和高度超过显示点
<!DOCTYPE HTML> <html> <head> <meta charset="gbk"> <title>ta ...
- node的优缺点及应用场景
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎(V8引擎执行Javascript的速度非常快,性能非常好) 可以说node是运行在服务器端V8引擎上的Ja ...