一.今日主要内容
1.了解python2和python3类的区别 python2在2.2之前使用的是经典类,2.2之后,使用的是新式类 class Foo: pass class Foo(object): pass MRO:method resolution order 方法的查找顺序 class Base: pass class Base1: def chi(): pass class Bar(Base,Base1): pass b=Bar() #Bar => Base=>Base1 b.chi() 2.经典类的MRO (树形结构的深度优先递归遍历,这个需要了解)=>树形结构的遍历 3.新式类的MRO C3算法(笔试或者面试别人的算法)(难点,重点)(python没有用过广度优先) (1)拆分 (2)合并 用头和身体比较 4.super() 找MRO顺序的下一个 #只有讲完MRO才能讲 5.一道面试题
二.今日内容大纲:
1.深度递归
2.MRO_C3
3.super
三.今日内容详解:
1.深度递归
class A: passclass B(A): passclass C(A): passclass D(B, C): passclass E: passclass F(D, E): passclass G(F, D): passclass I: passclass J(B, C): passclass K(A): passclass H(I, J, K): passclass Foo(H, G): pass
结果:
#FOO=>H=>I=>J=>B=>A=>C=>K=>G=>F=>D=>E
2.MRO_C3
class A: passclass B(A): passclass C(A): passclass D(B, C): passclass E(C, A): passclass F(D, E): passclass M: passclass N(M): passclass P(E, A): passclass X: passclass Q(P, N, X): passclass G(Q, F): passclass H(G, F): pass'''L(H) = H + L(G) + L(F) + GF # HGQPFDBECANMXL(G) = G + L(Q) + L(F) + QF # GQPFDBECANMX L(Q) = Q + L(P) + L(N) + X + PNX # QPECANMX (Q+PECA+NM+X+PNX)L(P) = P + L(E) + A + EA # PECAL(E) = E + L(C) + A + CA # ECAL(C) = C + A + A # CAL(N) = N + M # NML(F) = F + L(D) + L(E) + DE # FDBECAL(D) = D + L(B) + L(C) + BC # DBCA'''''' 求H的MRO 设求MRO的算法是L L(H) = H + L(G) + L(F) + GF L(G) = G + L(E) + E L(E) = E + L(C) + L(A) + CA L(C) = C + L(A) + A L(A) = A L(F) = F + L(D) + L(E) + DE L(D) = D + L(B) + L(C) + BC L(B) = B + L(A) + A # 加法:merge(), 拿第一项的第一位和 后面每项的除了第一位比较. 如果没有出现, 则该位元素算出 如果出现了. 此时开始下一项的第一位继续和后面每一项的除了第一位比较: 用头和后面身体比较 L(H) = H + L(G) + L(F) + GF # ECA + DBECA = HGFDBECAO L(G) = G + L(E) + E # GECA L(E) = E + L(C) + L(A) + CA # ECA L(C) = C + L(A) + A # CA L(A) = A L(F) = F + L(D) + L(E) + DE # FDBECA L(D) = D + L(B) + L(C) + BC # DBCA L(B) = B + A + A # BA'''print(H.__mro__)
3.super
(1)
class Base1: def chi(self): print('我是可怜的Base1')class Base2: def chi(self): print('我是可怜的Base2')class Base3: def chi(self): print('我是可怜的Base3')class Bar(Base1,Base2,Base3): def chi(self): print('我是Bar里面的吃') #super(类名,self) #从某个类开始找下一个MRO super(Bar,self).chi() #此时调用的super,在Bar调用=>super表示找MRO里的下一个 #super(Base1,self).chi() #super(Base2,self).chi()b = Bar() #顺序: Bar, Base1, Base2, Base3, objectb.chi()print(Bar.__mro__)
(2)
class Base1: def chi(self): super().chi() # super找的是MRO的下一个. print("我是可怜的Base1")class Base2: def chi(self): super().chi() print("我是可怜的Base2")class Base3: def chi(self): print("我是可怜的Base3")class Bar(Base1, Base2, Base3): def chi(self): print("我是Bar里面的吃1") # super(类名, self) 从某个类开始找下一个MRO super(Bar, self).chi() # 此时调用的super. 在Bar调用 -> super表示找MRO里的下一个 # super().chi() # super(Bar, self).chi() print("我是Bar里面的吃2")b = Bar() # 报错 如果是Base1 object,会报错,注意这里的细节b.chi() # 报错# 坑
(3)
# MRO + super ⾯试题class Init(object): #在下面对应子类和父类都可以 def __init__(self,v): #在这里注意解题的标记 print('init') #HaHa self.val=vclass Add2(Init): def __init__(self,val): print('Add2') super(Add2, self).__init__(val) #Pro print(self.val) self.val+=2class Mult(Init): def __init__(self,val): print('Mult') super(Mult,self).__init__(val) #Add2 self.val*=5class HaHa(Init): def __init__(self,val): print('哈哈') super(HaHa,self).__init__( val) #Mult self.val/=5class Pro(Add2,Mult,HaHa): #Incr passclass Incr(Pro): # incr->pro->add2->Mult->HaHa->init def __init__(self,val): super(Incr,self).__init__(val) #Add2 self.val+=1# print(Incr.__mro__)p=Incr(5)print(p.val)# Incr Pro Add2 Mult HaHa Init# p = Incr(5) # p.val = 8.0'''结果:# # Add2# # Mult# # 哈哈# # init# # 5.0# # 8.0'''p=Add2(2)print(p.val)# Add2, Init, Object c.val = 2# Add2# init# 2# 4'''MRO: method resolution order #方法查找顺序Incr,Pro,Add2,Mult,HaHa,Init,Object'''