当一个类中,包含了三个魔术方法(__get__,__set__,__delete__)之一,或者全部时,那么这个类就称为描述符类

浸染

描述符的浸染便是对一个类中的某个成员进行一个详细的管理操作(获取,赋值,删除) 描述符便是代理了一个类中的成员的操作,描述符属于类,只能定义为类的属性

三个魔术方法

'''__get__(self, instance, owner)触发机制:在访问工具成员属性时自动触发(当该成员已经交给描述符管理时)浸染:设置当前属性获取的值参数:1. self 描述符工具 2.被管理成员的类的工具。
3.被管理成员的类返回值:返回值作为成员属性获取的值把稳事变:无__set__(self, instance, value)触发机制:在设置工具成员属性时自动触发(当该成员已经交给描述符管理时)浸染:对成员的赋值进行管理参数:1. self 描述符工具 2.被管理成员的类的工具。
3.要设置的值返回值:无把稳事变:无__delete__(self, instance)触发机制:在删除工具成员属性时自动触发(当该成员已经交给描述符管理时)浸染:对成员属性的删除进行管理参数:1. self 描述符工具 2.被管理成员的类的工具。
返回值:无把稳事变:无'''

数据描述符:(完全)

php单态设计面向对象高阶描写符与设计模式 Bootstrap

同时具备三个魔术方法的类便是 数据描述符

非数据描述符:(不完全)

没有同时具备三个魔术方法的类便是 非描述符类

基本利用格式

把当前的描述符类赋值给一个须要代理的类中的成员属性

代码示例:

# 定义描述符类class PersonName(): __name = 'abc' def __get__(self, instance, owner): # print(self,instance,owner) return self.__name def __set__(self, instance, value): # print(self,instance,value) self.__name = value def __delete__(self, instance): # print(self,instance) # del self.__name print('不许可删除')# 定义的普通类class Person(): # 把类中的一个成员属性交给一个描述符类来实现 # 一个类中的成员的值是另一个描述符类的工具() # 那么当对这个类中得成员进行操作时,可以理解为便是对另一个工具的操作 name = PersonName()# 实例化工具zs = Person()print(zs.name)zs.name = '张三'print(zs.name)del zs.nameprint(zs.name)

描述符运用解析

#定义一个学生类,须要记录 学员的id,名字,分数class Student(): def __init__(self,id,name,score): self.id = id self.name = name self.score = score def returnMe(self): info = f''' 学员编号:{self.id} 学员姓名:{self.name} 学员分数:{self.score} ''' print(info)'''# 哀求:学员的分数只能在0-100范围中办理方法: 1。
在__init__方法中检测当前分数范围 # 检测分数范围 if score >= 0 and score <= 100: self.score = score 这个办理方案只能在工具初始化时有效。
2。
定义一个setattr魔术方法检测 检测如果给score分数进行赋值时,进行分数的检测判断 def __setattr__(self, key, value): # 检测是否是给score进行赋值操作 if key == 'score': # 检测分数范围 if value >= 0 and value <= 100: object.__setattr__(self, key, value) else: print('当前分数不符合哀求') else: object.__setattr__(self,key,value) 如果 学员的分数不止一个时怎么办,比如 语文分数,数学分数,英语分数 其余便是当前这个类中的代码是否就比较多了呢? 3。
可以思考利用描述符来代理我们的分数这个属性 1.定义Score描述符类 2.把学生类中的score这个成员交给描述符类进行代理 3.只要在代理的描述符类中对分数进行赋值和获取就ok了'''#定义描述符类 代理分数的管理class Score(): def __get__(self, instance, owner): return self.__score def __set__(self, instance, value): if value >= 0 and value <= 100: self.__score = value else: print('分数不符合哀求')# 利用描述符类代理score分数属性class Student(): score = Score() def __init__(self,id,name,score): self.id = id self.name = name self.score = score def returnMe(self): info = f''' 学员编号:{self.id} 学员姓名:{self.name} 学员分数:{self.score} ''' print(info)# 实例化工具zs = Student(1011,'张三疯',99)zs.returnMe()zs.score = -20zs.score = 88zs.returnMe()

描述符的三种定义格式

# 格式一 通过定义 描述符类来实现 推举'''class ScoreManage(): def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): passclass Student(): score = ScoreManage()'''# 格式二, 利用 property 函数 来实现'''class Student(): # 在当前须要被管理的类中 直接定义类似下面三个方法 def getscore(self): print('getscore') def setscore(self,value): print('setscore',value) def delscore(self): print('delscore') # 在 property 函数中指定对应的三个方法,对应的方法 1。
__get__,2。
__set__,3。
__delete__ score = property(getscore,setscore,delscore)zs = Student()# print(zs.score)# zs.score = 200# del zs.score'''# 格式三 利用 @property 装饰器语法来实现'''class Student(): __score = None @property def score(self): print('get') return self.__score @score.setter def score(self,value): print('set') self.__score = value @score.deleter def score(self): print('delete') del self.__scorezs = Student()# print(zs.score)zs.score = 199print(zs.score)del zs.score'''

设计模式

设计模式是前人为完成某个功能或需求,根据履历和总结,对实现的代码步骤和代码设计进行了总结和归纳,成为了实现某个需求的经典模式。

设计模式并不是固定的代码格式,而是一种面向工具编程的设计

单例(单态)设计模式

在当前脚本中,同一个类只能创建出一个工具去利用。
这种情形就成为单例(单态)。

'''实现单例的案例,思考:单例和婚姻法的关系,特殊像,一个人只能有一个结婚工具在社会中是如何完成一夫一妻制的?如果要结婚,必须要到 民政局 登记民政局 须要检测两个人的户口本,看上面是否属于 结婚的状态如果是已婚,肯定就撵出去了。
如果没有结婚,可以给盖个章了,开始登记。
那么按照这样的思路如何去实现 python中的单例设计模式呢?1。
须要有一个方法,可以去掌握当前工具的创建过程? 布局方法 __new__2。
须要有一个标示来存储和表示是否有工具 创建一个私有属性 进行存储,默认值为None3。
在创建工具的方法中去检测和判断是否有工具? 如果没有工具,则创建工具,并且把工具存储起来,返回工具 如果存储的是工具,则直接返回工具,就不须要创建新的工具了'''class Demo(): # 2.定义私有属性存储工具,默认值为None __obj = None # 1.定义布局方法 def __new__(cls, args, kwargs): # 3。
在创建工具的过程中,判断是否有工具 if not cls.__obj: # 判断如果没有工具,则创建工具,并且存储起来 cls.__obj = object.__new__(cls) # 直接把存储的工具返回 return cls.__obj# 实例化工具a = Demo()b = Demo()print(a)print(b)'''<__main__.Demo object at 0x106f4d850><__main__.Demo object at 0x106f4d850>'''

Mixin 稠浊设计模式

Mixin类

Mixin 必须是表示一种功能,而不是一个工具。

Mixin 的功能必须单一,如果有多个功能,那就多定义Mixin类

python 中的Mixin是通过多继续实现的

Mixin 这个类常日不单独利用,而是稠浊到其它类中,去增加功能的

Mixin 类不依赖子类的实现,即便子类没有继续这个Mixin,子类也能正常运行,可能便是短缺了一些功能。

利用Mixin混入类的好处?

1.Mixin 这个混入类的设计模式,在不对类的内容修正的条件下,扩展了类的功能

2.Mixin 混入类为了提高代码的重用性,使得代码构造更加大略清晰

3.可以根据开拓须要任意调度功能(创建新的Mixin混入类)避免设计多层次的繁芜的继续关系。

示例:

'''继续须要有一个必要的条件,继续该当是一个 'is-a' 的关系例如: 苹果可以去继续水果,由于苹果便是一个水果 苹果不能继续午饭,由于午饭可以有苹果也可以没有 比如 汽车可以继续 交通工具,由于汽车本身便是一个交通工具交通工具有哪些?汽车,飞机,直升机,这些都属于 交通工具那么如何去设计这些类的关系呢?比如创建一个交通工具类,然后属于交通工具的都来继续,再去实现。


但是,飞机和直升机都有翱翔的功能,而汽车并没有,那么在交通工具中如果去定义 翱翔这个功能,那就不太得当了。

能不能在飞机和直升机类等分别实现 翱翔 这个功能呢?可以,但是代码又无法重用。
怎么办?单独去定义交通工具类,和 翱翔器 这个两个父类,这样飞机和直升机就可以去继续这两个类.'''# 交通工具 vehicleclass vehicle(): # 运输货色 def huo(self): print('运输货色') # 搭载搭客 def ren(self): print('搭载搭客')# 翱翔器class FlyingMixin(): def fly(self): print('可以起飞了。


')# 定义汽车类class cart(vehicle): pass# 定义飞机class airplane(vehicle,FlyingMixin): pass# 定义直升机class helicopter(vehicle,FlyingMixin): pass# 此时去定义一个翱翔器的类 Flying,让须要翱翔的交通工具,直接继续这个类。
可以办理这个问题。
# 但是,1。
涌现类多继续,违背了'is-a' 2。
翱翔器这个类很随意马虎被误解# 办理方案也是利用多继续,但是给翱翔器这个类,定义成为一个 Mixin 稠浊类,# 此时便是即是把翱翔器这个类,作为了一个扩展的功能,来扩展其它类'''在上面的代码中,虽然直升机和飞机都利用了多继续,也便是继续了FlyingMixin但是由于 FlyingMixin 类加了 Minin这个名,就见告了后面阅读代码的人,这个类是一个Mixin类'''

抽象类(理解)

抽象类是一个分外的类: 1. 抽象类不能用,不能直接实例化成为一个工具。
2. 抽象类中包含了抽象方法,抽象方法便是没有实当代码的方法。
3. 抽象类须要子类继续,并重写父类的抽象方法。
才可以利用。

抽象类,一样平常运用在程序设计,程序设计中一样平常是要对功能和需求进行方案,个中有一些需求是明确的并且可以完成的,但是也可能会有一些需求是不明确的,或者不愿定详细须要怎么实现,那么此时就可以把这个不愿定怎么实现或者须要后面再去实现的方法,定义为抽象方法(只定义方法名,不写详细代码)抽象类的运用: 例如要开拓一个框架,这个框架要有一些基本功能和扩展功能。



但是你详细用这个框架开拓什么样的产品,开拓框架的人并不清楚或者确定。
因此框架就具备一定的功能,并且留下来一些方法的定义,剩下的便是须要自己在方法中详细实现自己业务逻辑。

抽象类的定义:

import abc# 如果要定义为抽象类,那么这个类的 metaclass属性必须是 metaclass=abc.ABCMetaclass WriteCode(metaclass=abc.ABCMeta): #须要抽象的方法,利用装饰器进行装饰 @abc.abstractmethod def write_php(self): pass def write_java(self): print('实现了java代码的开拓') def write_python(self): print('实现了python代码的开拓')# 抽象类不能直接实例化工具# obj = WriteCode()# print(obj)#TypeError: Can't instantiate abstract class WriteCode with abstract methods write_php# 定义子类,继续抽象类,并实现抽象类中的抽象方法class Demo(WriteCode): def write_php(self): print('实现了php代码的开拓')a = Demo()print(a)a.write_java()a.write_php()a.write_python()