1. 程式人生 > >python 面向物件(六)MRO C3演算法 super

python 面向物件(六)MRO C3演算法 super

########################總結################

面向物件回顧

  類:對某一個事物的描述,對一些屬性和方法的歸類

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