关于Python的super用法
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递。
举一个很常见的例子:
>>> class Foo:
def bar(self, message):
print(message)
>>> Foo().bar("Hello, World.")
Hello, World.
当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:
>>> class FooParent:
def bar(self, message):
print(message)
>>> class FooChild(FooParent):
def bar(self, message):
FooParent.bar(self, message)
>>> FooChild().bar("Hello, World.")
Hello, World.
这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:
>>> class FooParent:
def bar(self, message):
print(message)
>>> class FooChild(FooParent):
def bar(self, message):
super(FooChild, self).bar(message)
>>> FooChild().bar("Hello, World.")
Hello, World.
表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来,直接给例子:
代码一:
class A:
def __init__(self):
print("Enter A")
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
A.__init__(self)
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
A.__init__(self)
print("Leave C")
class D(A):
def __init__(self):
print("Enter D")
A.__init__(self)
print("Leave D")
class E(B, C, D):
def __init__(self):
print("Enter E")
B.__init__(self)
C.__init__(self)
D.__init__(self)
print("Leave E")
E()
结果:
Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E
执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。
代码二:
class A:
def __init__(self):
print("Enter A")
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
super(B, self).__init__()
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
super(C, self).__init__()
print("Leave C")
class D(A):
def __init__(self):
print("Enter D")
super(D, self).__init__()
print("Leave D")
class E(B, C, D):
def __init__(self):
print("Enter E")
super(E, self).__init__()
print("Leave E")
E()
结果:
Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E
在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照mro进行的(E.__mro__)。
疑难提醒:在python的普通中类中,继承的模式是深度优先的,也就是说对于一个对象的搜索遵循从左至右、从下到上的原则,而这从下到上的原则又优于从左至右。对本例: F E B C D A object
而对于新式类多继承,个人认为是一种按层查找的原则,会在较低层查找对象,如果没有的话再到较高层查找
原文来自:http://www.cnblogs.com/dkblog/archive/2011/02/24/1980654.html
关于Python的super用法的更多相关文章
- 关于Python的super用法研究
一.问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在python 2.2以前,通常的写法如代码段1: 代码段1: class A: def __init__(se ...
- python的super用法及含义
注释:以下都是在python2.7版本验证的 总括:1.python解决二义性问题,经历了深度优先算法.广度优先算法.拓扑排序算法,目前python的版本都是使用拓扑算法(C3) 2.严谨sup ...
- Python中super的用法
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承)等种种问题.总之前人留下的经验就是:保持一致性 ...
- python中super()的一些用法
在看python高级编程这本书的时候,在讲到super的时候,产生了一些疑惑,super在python中的用法跟其他的语言有一些不一样的地方,在网上找了一些资料,发现基本上很少有文章能把我的疑惑讲明白 ...
- Python中的super()用法
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this,比如:C#),用于传递对象本身,而在调用的时候则不 必显式传递,系统会自动传递. 今天我们介绍的主角是su ...
- Python中super的用法【转载】
Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143 收藏 展开 转载自 Python面向对象中super用法与MRO ...
- [python] super() 用法
问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如下: class A: def __init__(self): print & ...
- 由Python的super()函数想到的
python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...
- Python: 你不知道的 super
https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...
随机推荐
- spring MVC项目中,欢迎页首页根路径到底是怎么设置的
0. 问题: 如何改mvc中项目的欢迎页,或者叫做根路径 一个东西快弄完了,就剩下一个问题,应该是个小问题.就是mvc项目的欢迎页,怎么给改下呢. 这个项目是通过mvn建立的,整个项目的原型就是spr ...
- jquery.js有红叉
使用Eclipse 3.7及以上版本时,工程中加入jquery.min.js文件,发现该文件出现错误提示(红×),但使用Eclipse 3.7以前的版本就不会出现这种提示.是因为Eclipse 3.7 ...
- Entity Framework 一次加载许多个 Fluent API 映射
可通过多种方法来指定模型的 Fluent 映射(从类到数据库). 1.直接在 DbContext 类的 OnModelCreating 方法中进行映射,如下所示: protected overrid ...
- Windows下MySQLroot密码破解
Win下MySQL修改root密码的多种方法 ##win2003mysql的密码破解 方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PA ...
- 将double类型的值保留几位小数
1.第一个参数(3.1415926)是要处理的数值.第二个参数(1)为要保留的几位小数.第三个参数是按照“四舍五入”还是"直接取这一位的值"(MidpointRounding.To ...
- Berkeley DB数据处理
设计一个结构,利用Berkeley DB完成大数据的存储,备份,查询功能. 已有的储备: 1.Berkeley DB的基本操作. 2.数据转存后数据不丢失. 3.过百GB以上数据的存储. 数据流如下, ...
- 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)
分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...
- 我只知道一点非常简单的关于MVC的验证
我只知道一些非常简单的关于MVC的验证 如题,我只知道一点非常简单的关于MVC的验证,所以如果您接触过MVC的验证,相信也就不用看了,这个且当作是学习笔记吧. 先小讲解一下他基本的五个从Model里打 ...
- tar命令,转来等用
tar 解压缩命令 tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令 ...
- 使用maven多模块来构建系统时,spring初始化报错的问题
最近在实验maven结构的maven工程时,碰到一个问题,springbean总是初始化失败: Related cause: org.springframework.beans.factory.Uns ...