描述符
code:_15descriptor.py
# ************************************************************
"""
描述符:当一个类中包含了三个魔术方法(__get__(),__set__(),__delete__())之一,或者全部时,这个类就称为描述符类
作用:对一个类中的某个成员进行管理(获取、赋值、删除);只能定义为类的属性,只能属于类(不能是对象的成员)
把类中的一个成员属性交给一个描述符来实现
与C++:相当于C++中的容器
问题:要限制类中某个属性在一定范围内,需要如何实现?
1.在当前类声明中 初始化该属性时设置范围 对于赋值操作使用__setattr__()方法给该属性设置范围
2.使用描述符,设计描述符studentScore类
描述符分类:
1.数据描述符---完整描述符,同时具备三个魔术方法
2.非数据描述符---不完整描述符,没有同时具备三个魔术方法
描述符的三种定义方式:
1.定义描述符类(常用)--如下的PersonName类(推荐语法,后面两种会有些奇奇怪怪的问题)
2.使用property函数来实现,第一个方法对应__get__,第二个方法对应__set__,第三个方法对应__delete__
如下代码的Person中的__score描述符
3.使用@property
注意事项:使用描述符就不要使用__init__,会导致递归,,,奇奇怪怪的
"""
class PersonName:
__name = 'abc'
def __get__(self, inatance, owner):
return self.__name
def __set__(self, instance, value):
self.__name = value
def __delete__(self, instance):
del self.__name
class Person:
def scoreget(self):
return self.__score
def scoreset(self, value):
if 0 <= value <= 100:
self.__score = value
else:
print("分数范围不符合要求")
def scoredel(self):
del self.__score
name = PersonName()
# 这里特别奇怪,score必须是score形式不能是__score形式,不然那三个魔术方法无效;
# 而且在各个函数里面,__score必须是__score形式,不能是score形式,不然会报错,我也不知道为啥
score = property(scoreget, scoreset, scoredel)
# 还有这里也特别奇怪,在三个魔术方法内部必须是__iq的形式,不然就会报错
iq = 0
@property
def iq(self):
return self.__iq
@iq.setter
def iq(self,value):
if 0 <= value <= 300:
self.__iq = value
else:
print("__iq范围不符合要求")
@iq.deleter
def iq(self):
del self.__iq
class student:
name = 'name'
id = 'id'
score = 0
def __init__(self, n, i, s):
self.name = n
self.id = i
if 0 <= s <= 100:
self.score = s
else:
print("分数范围不符合要求")
def __setattr__(self, key, value):
if key == 'score':
if 0 <= value <= 100:
object.__setattr__(self, key, value)
else:
print("分数范围不符合要求")
else:
object.__setattr__(self, key, value)
def returnMe(self):
res = f""" 姓名:{self.name}
id:{self.id}
分数:{self.score} """
print(res)
Jasmine = Person()
Jasmine.name = 'Jasmine'
Jasmine.score = 99
Jasmine.iq = 100
print(f"Jasmine.name = {Jasmine.name}")
print(f"Jasmine.score = {Jasmine.score}")
print(f"Jasmine.iq = {Jasmine.iq}")
Jasmine.score = -10
Jasmine.iq = 399
print(f"Jasmine.score = {Jasmine.score}")
print(f"Jasmine.iq = {Jasmine.iq}")
del Jasmine.name
print(f"Jasmine.name = {Jasmine.name}")
Lily = student('lily', '2021110099', 99)
Lily.score = -10
Lily.returnMe()
Lily.score = 88
Lily.returnMe()
运行结果:
E:\Programs_Way\Python\python.exe D:/Prj/_PythonSelf/Object_oriented_programming/_15descriptor.py
Jasmine.name = Jasmine
Jasmine.score = 99
Jasmine.iq = 100
分数范围不符合要求
__iq范围不符合要求
Jasmine.score = 99
Jasmine.iq = 100
Jasmine.name = abc
分数范围不符合要求
姓名:lily
id:2021110099
分数:99
姓名:lily
id:2021110099
分数:88
Process finished with exit code 0