Python 经典类和新式类 super用法 (四)
来源:互联网 发布:dw淘宝全屏海报加热点 编辑:程序博客网 时间:2024/05/01 05:51
在Python2.x的2.2以上版本中,新式类是继承object的类。
经典类的MRO(基类搜索顺序)算法是深度优先。
新式类的MRO算法是C3算法。
经典类
class A:passclass B:passclass C(B):passclass D(C,A):pass基类搜索顺序:
D->C->B,->A
[D,C,B,A]
新式类
class A(object):passclass B(object):passclass C(B):passclass D(A,B):passclass E(C,D):pass
C3算法:
class B(A1,A2,A3...):passmro(B) = [B] + merge(mro(A1), mro(A2), mro(A3) ..., [A1,A2,A3])C3算法的核心是merge算法(查了半天资料才弄明白)
merge算法:如果一个序列的第一个元素,是其他序列中的第一个元素,或不在其他序列出现,则从所有执行merge操作序列中删除这个元素,合并到当前的mro中。
mro(A) = [A,O]mro(B) = [B,O]mro(C) = C + merge(mro(B),[B])= C + merge([B,O],[B]) #merge中的第一个队列的第一个元素B是后面的元素的第一个元素,所以取出,并删除所有列表中该元素= C + B + merge([O]) #第一个队列后面没有队列,所以没有该元素,所以取出,并删除所有列表中该元素= C + B + O= [C,B,O]mro(D) = D + merge(mro(A),mro(B),[A,B])= D + merge([A,O],[B,O],[A,B]) #merge中的第一个队列的第一个元素A不是后面的元素的第一个元素,但后面列表没有该元素,所以可以取出,并删除所有列表中该元素= D + A + merge([O],[B,O],B) #merge中的第一个队列的第一个元素O不是后面的元素的第一个元素,后面队列中也有该元素,所以不能取出,然后判断第二个列表的第一个元素(如果还不符合条件,依次处理)= D + A + merge([O],[B,O],B) #B是后面的元素的第一个元素,所以取出,并删除所有列表中该元素= D + A + B + merge([O],[O]) #O是后面的元素的第一个元素,所以取出,并删除所有列表中该元素= D + A + B + O= [D,A,B,O]mro(E) = E + merge(mro(C),mro(D),[C,D]) = E + merge([C,B,O],[D,A,B,O],[C,D]) #merge中的第一个队列的第一个元素C是后面的元素的第一个元素,所以可以取出,并删除所有列表中该元素= E + C + merge([B,O],[D,A,B,O],[D]) #merge中的第一个队列的第一个元素B不是队列的第一个元素,且存在于其他队列,所以取第二个列表的第一个元素D,D满足要求,所以可以取出,并删除所有列表中该元素= E + C + D + merge([B,O],[A,B,O]) #merge中的第一个队列的第一个元素B不是队列的第一个元素,且存在于其他队列,所以取第二个列表的第一个元素A,A满足要求,所以可以取出,并删除所有列表中该元素= E + C + D + A + merge([B,O],[B,O]) #merge中的第一个队列的第一个元素B是后面的元素的第一个元素,所以可以取出,并删除所有列表中该元素= E + C + D + A + B + merge([O],[O]) ##O是后面的元素的第一个元素,所以取出,并删除所有列表中该元素= E + C + D + A + B + O= [E,C,D,A,B,O]这个算起来挺麻烦,所以类的继承还是不要写的那么复杂了,维护起来也很麻烦的。
经典类和新式类实例
经典类
class A(): ret = 1 def __init__(self): pass class B(A): def __init__(self): pass class C(A): ret = 2 def __init__(self): pass class D(B, C): def __init__(self): pass#B->A->C x = D()print x.ret输出为:1
新式类
class A(object): ret = 1 def __init__(self): pass class B(A): def __init__(self): pass class C(A): ret = 2 def __init__(self): pass class D(B, C): def __init__(self): pass #B->C->A x = D()print x.ret输出为:2
super()
super(self,C).func() #调用的并不是其父类C的func,而是C在MRO中的下一个类的func,不能再经典类中使用
开始一直以为在多重继承的情况下选择执行某个父类的方法,网上有不少也是这么说的(被误导了)。
class A(object): def __init__(self): print "A" class B(object): def __init__(self): print "B" class C(object): def __init__(self): print "C" class D(A,B,C): def __init__(self): super(D,self).__init__() super(A,self).__init__() super(B,self).__init__() super(C,self).__init__() X = D()
会发现:
super(D,self).__init__()
执行的是A.__init__()
super(A,self).__init__()执行的是B.__init__()
super(B,self).__init__()
执行的是C.__init__()
super(C,self).__init__()执行的是Object.__init__()
这是因为mro(D)为:[ D, A, B, C, Object]
0 0
- Python 经典类和新式类 super用法 (四)
- Python中super的用法(新式类与经典类(旧式类)的区别)
- Python中super的用法(新式类与经典类(旧式类)的区别)
- Python新式类和经典类
- python 经典类和新式类
- 【Python】python 中新式类和经典类
- Python新式类和经典类的区别
- Python经典类和新式类的区别
- Python新式类和经典类的区别
- Python中新式类和经典类的区别
- python新式类和经典类的区别
- python新式类和经典类的区别?
- Python之经典类VS新式类和Supper
- Python新式类和经典类的区别
- python笔记: 经典类和新式类的区别
- Python新式类和经典类的区别
- Python3 新式类 和 经典类
- Python之旧式类、新式类(关键词:Python/旧式类/经典类/新式类)
- Fang Fang hdoj 5455 (字符串)
- UITableViewDataSource的代理方法
- 汉字转拼音类
- libevent
- oracle 基本技能
- Python 经典类和新式类 super用法 (四)
- 动态规划之背包问题初研究
- 2015北京网络赛 J Clarke and puzzle 分块+bitset
- 面对对象思想1
- ps -ef | grep **
- xcode
- el表达式的小知识点
- ZOJ 3811
- Anagrams问题