#描述符的应用;
#众所周知,python是弱类型的语言;但是,很多时候,我们在class实例化传参时,
# 需要限定不同的参数用不同的数据类型;这个时候就需要描述符的应用来代理要描述的参数
#描述符指:一个类,中重写了__get__()、__set__()、__delete__()方法中的一个,
# 但是,数据描述符都必须将三个函数重写;功能也要自己添加
class Typed():
def __init__(self,key,type):
'''
:param key: 描述的属性关键字
:param type: 所描述的属性期待的数据类型
'''
self.key=key
self.type=type
def __set__(self, instance, value):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
value :描述的对象的属性的值\即实例化的传参值
'''
#为了实现需求:限制传入参数的类型,这里采用if语句
if not isinstance(value,self.type):
raise TypeError("参数类型错误,%s的类型不是%s"%(self.key,self.type))
#抛出异常,你也可以不抛出异常,直接print
else:
instance.__dict__[self.key]=value
def __get__(self, instance, owner):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
owner :描述的对象的所属的类
'''
return instance.__dict__[self.key]
def __delete__(self, instance):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身
'''
instance.__dict__.pop(self.key)
#上面实现了数据描述符的编写,下面举例使用描述符
class People:
'''
总的来说:描述符描述属性,就是绕了一个弯,
调用了描述符类的__get__()、__set__()、__delete__()方法,
而不是在类自身的方法;
这样可以实现,参数类型的限制
'''
name=Typed("name",str)
age=Typed("age",int)
# 利用描述符代理属性,当People实例化时,就会触发Typed()实例化,
# 同时,触发__set__(),传入属性值在dict属性字典中;
# 在调用People实例对象的name\age属性时,会触发Typed()的__get__()方法
def __init__(self,name,age):
self.name=name
self.age=age
if __name__ == '__main__':
people=People("张三",18)#不会报错
print(people.name)
people1=People(12,"张三")#会报错
#描述符 + 装饰器 应用于类class,描述符用来限制参数类型,装饰器用来给类添加属性
#众所周知,python是弱类型的语言;但是,很多时候,我们在class实例化传参时,
# 需要限定不同的参数用不同的数据类型;这个时候就需要描述符的应用来代理要描述的参数
#描述符指:一个类,中重写了__get__()、__set__()、__delete__()方法中的一个,
# 但是,数据描述符都必须将三个函数重写;功能也要自己添加
class Typed():
def __init__(self,key,type):
'''
:param key: 描述的属性关键字
:param type: 所描述的属性期待的数据类型
'''
self.key=key
self.type=type
def __set__(self, instance, value):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
value :描述的对象的属性的值\即实例化的传参值
'''
#为了实现需求:限制传入参数的类型,这里采用if语句
if not isinstance(value,self.type):
raise TypeError("参数类型错误,%s的类型不是%s"%(self.key,self.type))
#抛出异常,你也可以不抛出异常,直接print
else:
instance.__dict__[self.key]=value
def __get__(self, instance, owner):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身,
owner :描述的对象的所属的类
'''
return instance.__dict__[self.key]
def __delete__(self, instance):
'''
注释:这个函数的参数是默认的;
instance ;实例对象本身
'''
instance.__dict__.pop(self.key)
#上面实现了数据描述符的编写,下面举例使用描述符
#结合:装饰器+描述符
def decorator(*args,**kwargs):
def wrapper(obj):
for key,type in kwargs.items():#将字典转换称元祖对:(key,type)
setattr(obj,key,Typed(key,type))#利用描述符添加属性,描述符主要限制类型;
return obj
return wrapper
@decorator(name=str,age=int,gender=str)
class People:
'''
总的来说:描述符描述属性,就是绕了一个弯,
调用了描述符类的__get__()、__set__()、__delete__()方法,
而不是在类自身的方法;
这样可以实现,参数类型的限制
'''
# 利用描述符代理属性,当People实例化时,就会触发Typed()实例化,
# 同时,触发__set__(),传入属性值在dict属性字典中;
# 在调用People实例对象的name\age属性时,会触发Typed()的__get__()方法
def __init__(self,name,age):
self.name=name
self.age=age
if __name__ == '__main__':
people=People("张三",18)#不会报错
print(people.name)
print(People.__dict__)
print(people.__dict__)
# people1=People(12,"张三")#会报错