关于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 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...
随机推荐
- Windows phone 中一些实用的控件
一.TextBlock:这个控件其实就是Label控件. <TextBlock x:Name="PageTitle" Text="page name" M ...
- 值类型的Constructor
使用C#的时候我们最熟悉的是类,也就是Reference Type,翻译成中文是引用类型.但是C#还有另外的一种类型往往被我们用的最多缺经常被忽视,这种类型就是值类型(Value Type). 值类型 ...
- margin的BUG
在进行简单的div盒子嵌套时,发现设置margin-top时存在bug,然后就去谷歌搜索了一下,发现margin确实存在bug. bug的现象是父子元素嵌套时,如果子元素是块元素时,对块元素设置mar ...
- mongodb持久化
先上一张图(根据此处重画),看完下面的内容应该可以理解. mongodb使用内存映射的方式来访问和修改数据库文件,内存由操作系统来管理.开启journal的情况,数据文件映射到内存2个view:pri ...
- laravel--has方法--查看关联关系
has()方法可以用来查询是否有关联关系的一个东西,一般其他的has方法 就是判断这个里面有没有值 $packageOrders = Company::has('packages')->get( ...
- php 文件上传一例简单代码
1.程序文件 <?php //判断临时文件存放路径是否包含用户上传的文件 if(is_uploaded_file($_FILES["uploadfile"]["tm ...
- jqueryGrid 内置的onclickSubmit afterSubmit
$(document).ready(function() { $('#jpgCustomers').jqGrid({ //url from wich data should be requested ...
- django post分号引发的问题
利用jquery的ajax传值 $.ajax({ type:"POST", url:"", data:"content"=content, ...
- C++中的struct和class的区别
C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能.struct能包含成员函数吗? 能!struct能继承吗? 能!!stru ...
- linux下bus,device,driver三者关系
linux下bus,device,driver三者关系 1.bus: 总线作为主机和外设的连接通道,有些总线是比较规范的,形成了很多协议.如 PCI,USB,1394,IIC等.任何设备都可以选择合适 ...