Python中super()的用法
参考链接:https://www.cnblogs.com/shengulong/p/7892266.html
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。总之前人留下的经验就是:保持一致性。要不全部用类名调用父类,要不就全部用 super,不要一半一半。
普通继承

class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print 'Parent'
def bar(self,message):
print message, 'from Parent'
class FooChild(FooParent):
def __init__(self):
FooParent.__init__(self)
print 'Child'
def bar(self,message):
FooParent.bar(self,message)
print 'Child bar function.'
print self.parent
if __name__=='__main__':
fooChild = FooChild()
fooChild.bar('HelloWorld')

super继承

class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print 'Parent'
def bar(self,message):
print message,'from Parent'
class FooChild(FooParent):
def __init__(self):
super(FooChild,self).__init__()
print 'Child'
def bar(self,message):
super(FooChild, self).bar(message)
print 'Child bar fuction'
print self.parent
if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar('HelloWorld')

程序运行结果相同,为:
Parent
Child
HelloWorld from Parent
Child bar fuction
I'm the parent.
从运行结果上看,普通继承和super继承是一样的。但是其实它们的内部运行机制不一样,这一点在多重继承时体现得很明显。在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照mro进行的(E.__mro__)。
注意:super继承只能用于新式类,用于经典类时就会报错。
新式类:必须有继承的类,如果没什么想继承的,那就继承object
经典类:没有父类,如果此时调用super就会出现错误:『super() argument 1 must be type, not classobj』
如果在子类中也定义了_init_()函数,那么该如何调用基类的_init_()函数:
方法一、明确指定 :
class C(P):
def __init__(self):
P.__init__(self)
print 'calling Cs construtor'
方法二、使用super()方法 :
class C(P):
def __init__(self):
super(C,self).__init__()
print 'calling Cs construtor'
c=C()
Python中的super()方法设计目的是用来解决多重继承时父类的查找问题,所以在单重继承中用不用 super 都没关系;但是,使用 super() 是一个好的习惯。一般我们在子类中需要调用父类的方法时才会这么用。
super()的好处就是可以避免直接使用父类的名字.主要用于多重继承,如下:
class A:
def m(self):
print('A')
class B:
def m(self):
print('B')
class C(A):
def m(self):
print('C')
super().m()
C().m()
这样做的好处就是:如果你要改变子类继承的父类(由A改为B),你只需要修改一行代码(class C(A): -> class C(B))即可,而不需要在class C的大量代码中去查找、修改基类名,另外一方面代码的可移植性和重用性也更高。
另外:避免使用 super(self.__class__, self),一般情况下是没问题的,就是怕极端的情况:
class Foo(object):
def x(self):
print 'Foo'
class Foo2(Foo):
def x(self):
print 'Foo2'
super(self.__class__, self).x() # wrong
class Foo3(Foo2):
def x(self):
print 'Foo3'
super(Foo3, self).x()
f = Foo3()
f.x()
注意:在 Foo2 中的 super(self.__class__, self) 导致了死循环,super 永远去找 Foo3 的 MRO 中的下一个类,super 的第一个参数应该总是当前的类,Python 没有规定代码必须怎样去写,但是养成一些好的习惯是很重要,会避免很多你不了解的问题发生。
总结
1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,
产生了一个super对象;
2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;
4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数
只调用一次(如果每个类都使用super);
5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一
个父类函数被调用多次。
Python中super()的用法的更多相关文章
- Python中super的用法【转载】
Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143 收藏 展开 转载自 Python面向对象中super用法与MRO ...
- Python中super的用法
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承)等种种问题.总之前人留下的经验就是:保持一致性 ...
- python中super的用法实例解析
概念 super作为python的内建函数.主要作用如下: 允许我们避免使用基类 跟随多重继承来使用 实例 在单个继承的场景下,一般使用super来调用基类来实现: 下面是一个例子: class Ma ...
- python中super().__init__和类名.__init__的区别
super().__init__相对于类名.__init__,在单继承上用法基本无差 但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次 多继承时 ...
- python 中del 的用法
python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...
- python中argparse模块用法实例详解
python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...
- 【313】python 中 print 函数用法总结
参考:python 中 print 函数用法总结 参考:Python print() 函数(菜鸟教程) 参考:Python 3 print 函数用法总结 目录: 字符串和数值类型 变量 格式化输出 p ...
- python中MySQLdb模块用法实例
篇文章主要介绍了python中MySQLdb模块用法,以实例形式详细讲述了MySQLdb模块针对MySQL数据库的各种常见操作方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了python中 ...
- python中hashlib模块用法示例
python中hashlib模块用法示例 我们以前介绍过一篇Python加密的文章:Python 加密的实例详解.今天我们看看python中hashlib模块用法示例,具体如下. hashlib ha ...
- Python Deque 模块使用详解,python中yield的用法详解
Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...
随机推荐
- AJAX-php-json数组
1.在php中有个数组,响应回前端 $array=["习大大","川普","金三胖"];2.JS对象数据格式 ex: 数组: var TOM ...
- 使用 kbmmw 的ORM开发纯REST数据库访问服务
运行环境: WIN 10 X64 delphi 10.2.2 kbmmw 5.05.11 Firefox 58.0.2 今天使用最新的kbmmw 版本做一个基于ORM的纯数据库访问的REST 服务器 ...
- 获取POM.XML依赖的JAR包
pom.xml 文件的依赖在本地仓库中,有些情况我需要根据pom.xml 抓取所有依赖的JAR包. 这个可以通过 ant 完成这个包的抓取. <target name="maven-j ...
- Win7 VS2015环境使用qt-msvc2015-5.6.0
QT下载 http://www.qt.io/download-open-source/#section-2 我用的是 qt-opensource-windows-x86-msvc2015-5.6.0. ...
- 深度优先搜索DFS和广度优先搜索BFS
DFS简介 深度优先搜索,一般会设置一个数组visited记录每个顶点的访问状态,初始状态图中所有顶点均未被访问,从某个未被访问过的顶点开始按照某个原则一直往深处访问,访问的过程中随时更新数组visi ...
- PHP continue break 区别 用法
<?php //continue 跳过当前循环,进行下一个 //break 终止当前循环 $db=new PDO("mysql:host=localhost;dbname=root&q ...
- 学以致用十-----centos7.2+python3.6+vim8.1+YouCompleteMe
趟过了之前的坑后,再来安装YouCompleteMe 一.安装依赖包 yum install libXt-devel gtk2-devel yum -y install python-devel ru ...
- 微信小程序之跨界面传参
微信小程序在两个之间传参类似js传递url拼接参数,举个例子来说吧 input自己设置参数 //index.wxml <form bindsubmit="formSubmit" ...
- ArcGIS API 和GIServer
ArcGIS API 和GIServer 先后以ArcGIS Server(9.3)和GIServer(2.2)为服务端,以ArcGIS API for Flex(1.2).ArcGIS API f ...
- C#重点内容之:委托(delegate)
为了记忆方便,提取了重点. 委托类似于指针,可以理解为函数指针的升级版,这是理解委托最关键的地方. Action和Func 系统自带的两种委托: Action Func Action型委托要求委托的目 ...