目录
面向对象高阶-描述符与设计魔术
描述符
当一个类中,包含了三个魔术方法(__get__,__set__,__delete__ )之一,或者全部时,那么这个类就称为描述符类
作用
描述符的作用就是对一个类中的某个成员进行一个详细的管理操作(获取,赋值,删除 描述符就是代理了一个类中的成员的操作,描述符属于类,只能定义为类的属性
使用格式
把当前的描述符类赋值给一个需要代理的类中的成员属性
三个魔术方法
(1)__get__( self, instance, owner)
触发机制:在访问对象成员属性时自动触发(当该成员已经交给描述符管理时)
作用:设置当前属性获取的值
参数:1. self 描述符对象 2. 被管理成员的类的对象 3. 被管理成员的类
返回值:返回值作为成员属性获取的值
注意事项:无
(2)__set__( self, instance, value)
触发机制:在设置对象成员属性时自动触发(当该成员已经交给描述符管理时)
作用:对成员的赋值进行管理
参数:1. self 描述符对象 2. 被管理成员的类的对象 3. 要设置的值
返回值:无
注意事项:无
(3)__delete__ (self, instance)
触发机制:在删除对象成员属性时自动触发(当该成员已经交给描述符管理时)
作用:对成员属性的删除进行管理
参数:1. self描述符对象 2. 被管理成员的类的对象
返回值;无
注意事项;无
数据描述符:(完整)
同时具备三个魔术方法的类就是数据描述符
非数据描述符:(不完整)
没有同时具备三个魔术方法的类就是非描述符类
基本使用格式
把当前的描述符类赋值给一个需要代理的类中的成员属性
#代码示例
#定义描述符类
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 __get__(self,instance):
#print(self,instance)
del self.__name
#定义的普通类
class PersonName():
__name = 'abc'
class Person():
#把类中的一个成员属性交给一个描述符类来实现
#一个类中的成员的值是另一个描述符类的对象()
#那么当对这个类中得成员进行操作时,可以理解为就是对另一个对象的操作
name = PersonName()
#实例化对象
zs = Person()
print(zs.name)
zs.name = '张三'
print(zs.name)
del zs.name
print(zs.name)
描述符应用案例
# 定义描述符类 代理分数的管理
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 = -20
zs.score = 88
zs.returnMe()
描述符的三种定义格式
'''格式一通过定义描述符类来实现(推荐)'''
class ScoreMange():
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
pass
def __delete__(self,instance) :
pass
class student():
score = ScoreMange()
# 格式二,使用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.score
zs = Student()
# print(zs.score)
zs.score = 199
# print(zs.score)
del zs.score