python 面向物件(六)MRO C3演算法 super
阿新 • • 發佈:2018-12-24
########################總結################
面向物件回顧
類:對某一個事物的描述,對一些屬性和方法的歸類
class 類名: var=123#類變數 def __init__(self,x,x,x)#例項變數 self.xxx=xxx self.xxx=xxx self.xxx=xxx #例項方法:給物件用的 def method(self): pass @staticmethod():--函式 def stsmethod():pass @classmethod--方法 def clsmethod(cls): pass @property def age(self):#把一個方法變成屬性 retun 10 def __privatemethod(slef):私有方法 pass 類可以互相繼承 class Base:#超類 基類 pass class Person(Base,Base2):#派生類 pass 約束1.寫一個父類,在父類中寫出要被約束的方法, raise NotImplmentedError() 2.寫一個抽象類,子類重寫抽象類中的抽象方法 from abc import ABCMeta,abstractmethod class Foo(metclass=ABCMeta): @abstractmethod def 抽象方法(self): pass 反射 getattr(物件,str) hasattr(物件,str) setattr(物件,strt,value) delattr(物件,strt)
2. 明白物件是什麼
什麼是物件, 什麼都是物件.
在程式設計的世界裡. 物件是由類建立.
類名() -> 建立物件, 例項化
此時會預設的呼叫兩個方法 -> __new__()開闢記憶體 -> __init__()
物件能夠執行的方法都寫在類中. 物件的屬性一般都寫在__init__()
物件最主要的意義就是對資料進行封裝.
class Stu:
def __init__(self, name, sno, age):
self.name = name
self.sno = sno
self.age = age
bb = Stu("寶寶", "1", 18)
python 在2.4之前使用的是經典類 2.4之後使用新式類
經典類的mro 樹形結構深度優先遍歷
從左往右 一條道走到黑
class A: pass class B(A): pass class C(A): pass class D(B,C): pass class E(C,A): pass class F(D,E): pass class G(E): pass class H(G,F): pass #加法 merge() 拿第一項和後面每項的第一位比較,如果沒有則計算出 如果出現了,此時開始下一項的第一位 頭和身體的比較
新式類的mor C3演算法
L(H)= H +L(G)+L(F)+GF h+geca+fdbeca =hgfdbeca L(G)= G +L(E)+E g+eca+e =geca L(F)= F +L(D)+L(E)+DE f+dbca+eca+de =fdbeca L(E)= e +l(C)+L(A)+CA e+ca+a+ca =eca L(D)= D +L(B)+L(C)+BC D+ba+ca+bc =dbca 比到c的時候第二位沒有就寫上 L(C)= C +L(A)+A ca L(B)= B +L(A)+A ba L(A)= A print(H.__mro__)
super() 找MRO順序的下一個
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裡面的吃1") # super(類名, self) 從某個類開始找下一個MRO super(Base2, self).chi() # 此時呼叫的super. 在Bar呼叫 -> super表示找MRO裡的下一個 # super().chi() # super(Bar, self).chi() print("我是Bar裡面的吃2") b = Bar() # Bar, Base1, Base2, Base3, object b.chi() print(Bar.__mro__)
###################結果#################
我是Bar裡面的吃1
我是可憐的Base3
我是Bar裡面的吃2
(<class '__main__.Bar'>, <class '__main__.Base1'>, <class '__main__.Base2'>, <class '__main__.Base3'>, <class 'object'>)
############一道 面試題###########
# MRO + super 面試題 class Init(object): def __init__(self, v): # 2 print("init") self.val = v class Add2(Init): def __init__(self, val): # 2 print("Add2") super(Add2, self).__init__(val) # Mult print(self.val) self.val += 2 class Mult(Init): def __init__(self, val): print("Mult") super(Mult, self).__init__(val) # Haha self.val *= 5 class HaHa(Init): def __init__(self, val): print("哈哈") super(HaHa, self).__init__(val) # Init self.val /= 5 class Pro(Add2,Mult,HaHa): # pass class Incr(Pro): # def __init__(self, val): # 5 super(Incr, self).__init__(val) # Add2 self.val += 1
p = Incr(5)
print(p.val)
c=Add2(2)
print(v.cal)
先算mro
L(Incr)=Incr+l(Pro)+Pro Incr+pro,Add2,Mult,HaHa,init+Pro 結果Incr+pro+Add2,Mult,HaHa,init L(Pro)=Pro+l(Add2)+l(Mult)+l(HaHa)+Add2+Mult+HaHa #因為Add2,Mult,HaHa繼承的都是init L(Pro)=Pro+Add2,init+Mult,init+HaHa,init+Add2,Mult,HaHa 計算結果:pro,Add2,Mult,HaHa,init
# p = Incr(5) # p.val = 8.0 # # Add2 # # Mult # # 哈哈 # # init # # 5.0 # # 8.0 # print(p.val) # c = Add2(2) # Add2, Init, Object c.val = 2 # Add2 # init # 2 # 4