Python的多重继承和super
来源:互联网 发布:计算圆周率的算法 编辑:程序博客网 时间:2024/05/16 19:49
多重继承:
super:
不要一说到 super 就想到父类!super 指的是 MRO 表中的下一个类!super 其实干的是这件事:
def super(cls, inst): mro = inst.__class__.mro() # Always the most derived class return mro[mro.index(cls) + 1]
两个参数 cls 和 inst 分别做了两件事:
1. inst 负责生成 MRO 的 list
2. 通过 cls 定位当前 MRO 中的 index,并返回 mro[index + 1]
举例:
class Root(object):
def __init__(self):
print 'this is Root'
class B(Root):
def __init__(self):
print 'enter B'
super(B, self).__init__()
print 'leave B'
class C(Root):
def __init__(self):
print 'enter C'
super(C, self).__init__()
print 'leave C'
class D(B, C):
pass
d = D()
print d.__class__.__mro__
输出:
enter B
enter C
this is Root
leave C
leave B
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Root'>, <type 'object'>)
解释:
在 B 的 __init__() 函数中:
super(B, self).__init__()
首先,我们获取 self.__class__.__mro__,这里的 self 是 D 的 instance:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Root'>, <type 'object'>)
然后,通过 B 定位 MRO 中的 index,并找到下一个,显然是 C,于是,调用 C 的 __init__ 打印 enter C。
1)在 MRO 中,基类永远出现在派生类后面,如果有多个基类,基类的相对顺序保持不变。
2)super 是针对新式类的,如果用旧式类,就应该用类名去调用方法。
最后看两个列子:
例子1:
[root@zj py]# cat super1.py
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(object):
def __init__(self):
print "enter B"
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):
def __init__(self):
print "enter E"
B.__init__(self)
C.__init__(self)
print "leave E"
class F(E, D):
def __init__(self):
print "enter F"
E.__init__(self)
D.__init__(self)
print "leave F"
f = F()
[root@zj py]# python super1.py
enter F
enter E
enter B
leave B
enter C
enter D
enter A
leave A
leave D
leave C
leave E
enter D
enter A
leave A
leave D
leave F
[root@zj py]#
例子2:
[root@zj py]# cat super2.py
class A(object):
def __init__(self):
print "enter A"
super(A, self).__init__() # new
print "leave A"
class B(object):
def __init__(self):
print "enter B"
super(B, self).__init__() # new
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):
def __init__(self):
print "enter E"
super(E, self).__init__() # change
print "leave E"
class F(E, D):
def __init__(self):
print "enter F"
super(F, self).__init__() # change
print "leave F"
f = F()
[root@zj py]# python super2.py
enter F
enter E
enter B
enter C
enter D
enter A
leave A
leave D
leave C
leave B
leave E
leave F
[root@zj py]#
说明:
总结一下:
1. super 并不是一个函数,是一个类名,形如 super(B, self) 事实上调用了 super 类的初始化函数,产生了一个 super 对象;
2. super 类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
3. super(B, self).func 的调用并不是用于调用当前类的父类的 func 函数;
4. Python 的多继承类是通过 mro 的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用 super);
3. super(B, self).func 的调用并不是用于调用当前类的父类的 func 函数;
4. Python 的多继承类是通过 mro 的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用 super);
5. 混用 super 类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。
6. 用 super,遇到修改父类的名字时等情况,可以少修改代码,参考:http://www.jb51.net/article/66912.htm
参考:
https://www.zhihu.com/question/20040039
http://blog.csdn.net/imzoer/article/details/8737642#
https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
http://stackoverflow.com/questions/15896265/python-super-inheritance-and-arguments-needed/15896594#15896594
http://www.jb51.net/article/66912.htm
0 0
- Python的多重继承和super
- python 27 super继承(解决多重继承时,老办法init父类多次的问题)
- python 27 super继承(解决多重继承时,老办法init父类多次的问题)
- python的多重继承
- python的多重继承
- python的多重继承
- python的多重继承
- Python的多重继承和Java的单继承
- python学习笔记(22)--类的详解4-多重继承(super()函数)
- python普通继承和super继承
- Python 里的多重继承
- Python 里的多重继承
- python 继承多重继承
- 继承和super的用法
- Python学习:多继承和super()
- python继承中super的问题
- 关于python的继承,super关键字
- python的多重继承与多态
- android studio创建assets目录并且利用webView加载其html(by 星空武哥)
- LeetCode 72. Edit Distance(编辑距离)
- [leetcode]【数组】81. Search in Rotated Sorted Array II
- SciTe 中文设置(解决乱码,中文界面)
- 日常笔记之【+“”】
- Python的多重继承和super
- Spring事务的传播行为和隔离级别
- 使用diskpart命令修复U盘分区
- PAT乙级—1038. 统计同成绩学生(20)-native
- URAL 1994 The Emperor's plan(dp、期望)
- 深入理解JVM内幕:从基本结构到Java 7新特性
- 202. Happy Number
- java学习、java入门我为什么要学习Java EE?
- oracle linux 5.9 不支持 acfs 文件系统 怎么解决呢?