时间:2021-05-22
功能
super功能:super函数是子类用于调用父类(超类)的一个方法。
用法
1.在子类 __init__() 方法中正确的初始化父类,保证相同的基类只初始化一次。
2.覆盖特殊方法。
3.解决多重继承中,子类重复调用父类方法的问题。
注意
super()继承只能用于新式类,用于经典类时就会报错。
新式类:必须有继承的类,如果无继承的,则继承object
经典类:没有父类,如果此时调用super就会出现错误:『super() argument 1 must be type, not classobj)
在子类__init__()方法中正确初始化父类,保证相同的基类只初始化一次
假如说在父类中实现了一个方法,你想在子类中使用父类的这个方法并且做一定扩展但是又不想完全重写,并且这个场景中的继承属于多继承,那么super()就出场了,可以实现方法的增量修改。
A(父类)有x属性,B(子类)想添加y属性:
覆盖Python特殊方法
在上面代码中,__setattr__() 的实现包含一个名字检查。 如果某个属性名以下划线(_)开头,就通过 super() 调用原始的 __setattr__() , 否则的话就委派给内部的代理对象 self._obj 去处理。 这看上去有点意思,因为就算没有显式的指明某个类的父类, super() 仍然可以有效的工作。
解决多重继承中,子类重复调用父类方法的问题
尽管对于大部分代码而言这么做没什么问题,但是在更复杂的涉及到多继承的代码中就有可能导致很奇怪的问题发生。 比如,考虑如下的情况:
class Base: def __init__(self): print('Base.__init__')class A(Base): def __init__(self): Base.__init__(self) print('A.__init__')class B(Base): def __init__(self): Base.__init__(self) print('B.__init__')class C(A,B): def __init__(self): A.__init__(self) B.__init__(self) print('C.__init__')如果你运行这段代码就会发现 Base.__init__() 被调用两次,如下所示:
>>> c = C()Base.__init__A.__init__Base.__init__B.__init__C.__init__>>>可能两次调用 Base.__init__() 没什么坏处,但有时候却不是。 另一方面,假设你在代码中换成使用 super() ,结果就很完美了:
class Base: def __init__(self): print('Base.__init__')class A(Base): def __init__(self): super().__init__() print('A.__init__')class B(Base): def __init__(self): super().__init__() print('B.__init__')class C(A,B): def __init__(self): super().__init__() # Only one call to super() here print('C.__init__')运行这个新版本后,你会发现每个 __init__() 方法只会被调用一次了:
>>> c = C()Base.__init__B.__init__A.__init__C.__init__>>>为了弄清它的原理,我们需要花点时间解释下Python是如何实现继承的。 对于你定义的每一个类,Python会计算出一个所谓的方法解析顺序(MRO)列表。 这个MRO列表就是一个简单的所有基类的线性顺序表。例如:
>>> C.__mro__(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,<class '__main__.Base'>, <class 'object'>)>>>为了实现继承,Python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。 我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
老实说,你所要知道的就是MRO列表中的类顺序会让你定义的任意类层级关系变得有意义。
当你使用 super() 函数时,Python会在MRO列表上继续搜索下一个类。 只要每个重定义的方法统一使用 super() 并只调用它一次, 那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次。 这也是为什么在第二个例子中你不会调用两次 Base.__init__() 的原因。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
详解Java使用super和this来重载构造方法实例代码://父类classanotherPerson{Stringname="";Stringage="";
详解java中this.getClass()和super.getClass()的实例前言:遇到this.getClass()和super.getClass()的
Python中格式化format()方法详解Python中格式化输出字符串使用format()函数,字符串即类,可以使用方法;Python是完全面向对象的语言,
Python操作MySQL详解及实例使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能是MySQLdb),PyMySQL和
Linuxtraceroute命令使用方法实例详解一、默认使用的是UDP协议(30000以上端口)二、使用TCP协议-T-p三、使用ICMP协议-I四、实战[r