初识面向对象(钻石继承,super,多态,封装,method,property,classmethod,staticmethod)...

it2022-05-05  107

组合 什么有什么的关系 一个类的对象作为另一个类的对象继承 子类可以使用父类中的名字(静态属性 方法)抽象类和接口类 只能不继承,不能被实例化 子类必须实现父类中的同名方法———规范代码 metaclass=ABCMeta @abstractmethod python 支持多继承,对于python 来说,抽象类和接口类没有区别 接口类是python 特有的,因为Pythonz直接用类就可以实现接口的效果 python没有'接口'这种数据类型,java中有 继承多态封装propertyclassmethodstaticmethod钻石继承 class A: def func(self):print('in A') class B(A): def func(self):print('in B') class C(A): def func(self):print('in C') class D(B,C): def func(self): print('in D') d=D() d.func()#in D class A: def func(self):print('in A') class B(A):pass # def func(self):print('in B') class C(A):pass # def func(self):print('in C') class D(B,C):pass # def func(self): print('in D') d=D() d.func()#in A 钻石继承--4个类图形D->B->C->A class E: def func(self):print('in E') class D: def func(self):print('in D') class C(E): def func(self):print('in C') class B(D):pass # def func(self):print('in B') class A(B,C):pass # def func(self):print('in A ') d=D() d.func()#in D 走最合理的路 class F: def func(self):print('in F') class E(F): def func(self):print('in E') class D(F): def func(self):print('in F') class C(E): def func(self):print('in C') class B(D): def func(self):print('in B') class A(B,C): def func(self):print('in A')#遵循广度优先的原则 print(A.mro())#打印的是A 的找值顺序[<class '__main__.A'>, <class '__main__.B'>, ...]A,B,D,C,E,F super class List(list): def append(self, obj): if type(obj) is str: super().append(obj)#调用父类的方法,list.append(obj) else: # print(f'{obj}不是字符串类型') print('%s不是字符串类型' % obj) def show_middle(self): return self[int(len(self) / 2)]#返回以长度的一半为索引的self的值 li = List('hello word22222')#['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd', '2', '2', '2', '2', '2', '18', 'abc'] li.append('18') li.append('abc') print(li) print(li.show_middle())#r class A: def func(self): print('A') class B(A): def func(self): print('B') super().func() class C(A): def func(self): print('C') super().func() class D(B,C): def func(self): print('D') super().func() D().func()#D,B,C,A print(D.mro())#打印的是A 的找值顺序D->B->C->A B().func()#B,A print(B.mro())#打印的是A 的找值顺序B->A super并不是单纯的找父类,和mro的顺序是玩完全对应的 新式类:python 3里全部是新式类 新式类默认继承objectpy2里面 新式类 主动继承object 经典类 不主动继承object--遵循深度优先算法,没有mro 方法,没有super python 动态强类型语言 弱类型 1+'2' 参数的数据类型也不需要指定 强类型 同类型之 间可以做运算 参数的数据类型也需要指定 在python的经典类中,方法解析顺序是深度优先算法 事实上,对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序 在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果。

C3算法的本质就是Merge,不断地把mro()函数返回的序列进行Merge,规则如下:

1. 如果第一个序列的第一个元素,是后续序列的第一个元素,或者不再后续序列中再次出现,则将这个元素合并到最终的方法解析顺序序列中,并从当前操作的全部序列中删除。

2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

举例:

# 归并算法 C3算法 class A:pass class B(A):pass class C(A):pass class D(B):pass class E(C):pass class F(D,E):pass # 第一步 先找出F类的父类的MRO D [D,B,A,O] E [E,C,A,O] # 变形为:merge([D,B,A,O], [E,C,A,O], [D,E]) # 第一个表的表头 后面所有的表去掉表头部分不能含有这个D FD merge([B,A,O], [E,C,A,O], [E]) # 先将D取出来 FDB merge([A,O], [E,C,A,O], [E]) # 再将B取出来 # 不满足条件时 取二个 FDBE merge([A,O], [C,A,O]) # 将第二个列表E取出来 FDBEC merge([A,O], [A,O]) # 将第二个列表里的C取出来,此时取值完成 FDBECAO # F的继承顺序为FDBECAO # 注意:这是模仿内部的查找机制做的示例,并非真实原理 多态 python天生自带多态什么是多态java多态 class Foo:pass class list(Foo):pass class dict(Foo):pass class str(Foo):pass def len(a): print(a) len(1)

封装

封装成一个函数封装成一个类封装 面向对象的特性 class A: __静态属性='aaa' #私有的静态属性 print(__静态属性)#aaa __静态属性,在内部的储存方式为_类名__名字,例如_A__静态属性 在一个变量前加上两个下划线是有特殊意义的,将变量变成私有的 print(A.__静态属性)#报错,私有的名字不能在类的外部使用 print(A.__dict__)#将类的内容打印出来 print(A._A__静态属性)#从语法的角度上不允许直接调用 aaa A.__wahahaha='hahaha'#在一个类的外部是不可能定义一个私有名字的 ,此处的hahaha是普通变量 print(A.__dict__) 私有的对象属性 class Room: def __init__(self,owner,id,length,width,height): self.owner=owner self.id=id self.__length=length self.__width=width self.__height=height def area(self): return self.__length*self.__width #这里 self.__length在内存里是self._Room__length r=Room('小灰灰',301,1,1,0.5) print(r.area())#1 私有的方法不希望从外部去调用这个方法,不独立完成一个功能,而是类整体完成某个功能的一部分 class Student:#理解 def __init__(self,name,pwd): self.name=name self.__pwd=pwd def __getpwd(self): return self.__pwd[::-1] def login(self): return self.__getpwd() s=Student('xiaohua','abc') print(s.login())#cba class A: def __init__(self): self.func() def func(self): print('A') class B(A): def func(self): print('B') B()#B 用的是父类class A 的__init__方法,调用的是自己的func函数 class A: def __init__(self): self.__func() #_A__func def __func(self): print('A') class B: def __func(self): print('B') def __init__(self): self.__func() #_B__func B()#B class A: def __init__(self): self.__func() #_A__func def __func(self): print('A') class B: def __init__(self): self.__func() #_B__func B()#报错,找不到_B__func的对象 名字 共有的 在类的外部用 内部用 子类用 私有的 在类的内部用私有的概念和面试题 ***私有的属性和静态属性***私有方法**几个装饰器函数 propertyclassmothodstaticmethod装饰器圆形半径r面积area周长 perimeter from math import pi class Circle: def __init__(self,r): self.r=r @property#将一个方法伪装成一个属性 def area(self): return pi*self.r**2 @property def perimeter(self): return 2*pi*self.r r1=Circle(3) print(r1.area)#相当于不加装饰前的r1.area() print(r1.perimeter)#相当于不加装饰前的r1.perimeter()

 

class Person: def __init__(self,name): self.__name=name @property#将一个方法伪装成一个属性 def name(self): return self.__name @name.setter#将这个属性进行修改 def name(self,new): if type(new) is str: self.__name=new a=Person('egon') print(a.name)#egon a.name='alex'#不能直接改 print(a.name)#alex class Demo: def __init__(self,wahaha): self.__wahaha=wahaha @property#将一个方法伪装成属性 def wahaha(self): print('in wahaha') return self.__wahaha @wahaha.setter def wahaha(self,new): self.__wahaha=new d=Demo('abc') print(d.wahaha)#123 可以被查看 d.wahaha=123#可以被修改 print(d.wahaha)#123 class Goods: def __init__(self,discount,origin_price): self.__discount=discount self.__price=origin_price @property def price(self): return round(self.__discount*self.__price,2)#保留两位小数 @price.setter def price(self,new): self.__price=new d=Goods(0.8,10) print(d.price)#8.0 d.price=12 print(d.price)#9.6 一个属性 可以被查看 可以被修改 可以被删除 class A:pass a=A() a.name='egon' print(a.__dict__)#{'name': 'egon'} del a.name print(a.__dict__)#{} class A: def __init__(self, path): self.__f = open(path, 'w') # 创建属性的方式可以改变 @property def f(self): return self.__f @f.deleter def f(self): self.close()#所有的借用操作系统的资源,在删除一个变量之前必须先归还资源 del self.__f def write(self,content): self.__f.write(content) def close(self): self.__f.close()#上面的self.close()=self.__f.close() obj=A('heheda') obj.write('窗前明月光,地上鞋两双') obj.close()#所有的借用操作系统的资源,在删除一个变量之前必须先归还资源 del obj.f#f 文件删除,文件没有关 print(obj.f) property***setter**deleter* class Goods: __discount=0.8 def __init__(self,origin_price): self.__price=origin_price @property def price(self): return round(self.__price*Goods.__discount,2)#Goods.__discount.调用静态变量 @price.setter def price(self,new_price): self.__price=new_price @classmethod def change_discount(cls,new_discount): print(cls,Goods)#此时的cls和Goods是一样的 Goods.__discount=new_discount # cls.__discount=new_discount banana=Goods(10) print(banana.price)#8 banana.change_discount(1)#10 恢复原价 print(banana.price) class Student: def __init__(self,name,sex): self.name=name self.sex=sex @staticmethod #相当于函数 def login(): name=input('>>') if name=='alex': print('登录成功') # 学生的登录行为 Student.login()

 

method 方法--函数 由实例化对象去调用property 伪装成属性的一种方法 --特性 由实例化对象去调用classmethod 类方法 由类调用,只用用类中的静态变量staticmethod 静态方法 由类调用,一个方法既不会用到对象的属性,也不会用到类的属性

转载于:https://www.cnblogs.com/daofaziran/p/9102513.html

相关资源:各显卡算力对照表!

最新回复(0)