#装饰器
def decorator(obj):
def wrapper(*args,**kwargs):
'''
函数里面可以操作自己想加入的功能;
加上*args,**kwargs两个参数,即表示:
无论被修饰的函数/类有几个参数、什么类型,都可以用该装饰器装饰,
如果,没有写这两个参数,那就必须被装饰的函数/类有
几个参数,装饰器就写死为几个参数;就达不到想要的效果
'''
print("执行装饰器")
res=obj(*args,**kwargs)
return res
return wrapper
#装饰器可装饰函数:
@decorator
def add(x,y):
return x+y
#装饰器可装饰类:
@decorator
class Math:
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
def shengfa(self):
return self.x * self.y * self.z
if __name__ == '__main__':
a=add(2,3)
print(a)
m=Math(1,2,3)
print(m.shengfa())
#描述符 + 装饰器 应用于类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,"张三")#会报错
装饰器的写法不一;按照需求来写;