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
不怕大牛比自己牛,就怕大牛比自己更努力