#装饰器:本质就是函数,功能就是为其他函数添加附加功能
#原则
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
#高阶函数
定义:1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名 (满足其一即可)
#简单的装饰器 import time def timer(func): def wrapper(): #*args接受元组系列 **kwargs接收字典系列 start_time=time.time() res=func() #函数嵌套 stop_time=time.time() print('All time %d' %(stop_time-start_time)) return res return wrapper @timer #相当于text=timer(text) def text(): time.sleep(3) print("end.....") text()
def list_diedai(fun):
def wrapper(*args,**kwargs): #*args=(num) **kwargs={'num':4}
res=fun(*args,**kwargs) #*args将接收的参数转化成列表
return res.__iter__ #**kwargs将接受的参数转化成字典
return wrapper #返回地址
@list_diedai
def list1(num):
return [x for x in range(int(num))]
p1=list1(4)
print(p1) #<method-wrapper '__iter__' of list object at 0x009D45A8>
print(p1()) #<list_iterator object at 0x00A93250>
p2=p1()
print(p1().__next__()) # 0
print(next(p1())) # 0
print(p2.__next__()) # 0
print(next(p2)) # 1
print(next(p2)) # 2
print(p2.__next__()) # 3
#类的装饰器(进阶)
#万能参数添加器
def Type(**kwargs):
print(kwargs) #{'x': 7, 'j': 9}
def deco(obj):
print(obj) #<class '__main__.Int'>
for key,val in kwargs.items():
setattr(obj,key,val)
return obj
print(deco) #<function Type.<locals>.deco at 0x01760AE0>
return deco
@Type(x=7,j=9)
class Int:
pass
#装饰器应用进阶
class Type:
def __init__(self,x,excepet_type): #巧妙灵活
self.x=x
self.excepet_type=excepet_type
def __get__(self, instance, owner):
# print(instance,owner)
return instance.__dict__[self.x]
def __set__(self, instance, value):
# print(instance,value)
if type(value)!=self.excepet_type:
print('%s 传入的不是 %s ,错误!!!' %(self.x,self.excepet_type))
return
instance.__dict__[self.x]=value
def __delete__(self, instance):
instance.__dict__.pop(self.x)
def Type1(**kwargs):
def warpper(obj):
for key,val in kwargs.items():
setattr(obj,key,Type(key,val))
return obj
return warpper
@Type1(name=str,age=int) #先运行Type1(name=str,age=int)函数
#得到warpper的返回值,在运行 People=warpper(People)
class People:
# name=Type('name',str) #描述符代理
# age=Type('age',int)
def __init__(self,name,age,salary):
self.name=name
self.age=age
self.salary=salary
p=People('lujiacheng','3',5000) #age 传入的不是 <class 'int'> ,错误!!!
print(p.__dict__) #{'name': 'lujiacheng', 'salary': 5000}
p.name=98 #name 传入的不是 <class 'str'> ,错误!!!
print(p.__dict__) #{'name': 'lujiacheng', 'salary': 5000}
p.name='98'
print(p.__dict__) #{name': '98', 'salary': 5000}
del p.name
print(p.__dict__) #{'salary': 5000}
#类装饰器
class lazyproperty:
def __init__(self,fun):
self.func=fun
def __get__(self, instance, owner):
if instance is None:
return self
return self.func(instance)
class Room:
def __init__(self,name,width,length):
self.name=name
self.width=width
self.length=length
# @property # area=property(area)
@lazyproperty
def area(self):
return self.width*self.length
r=Room('dd',45,56)
print(r.area) # 2520
print(Room.area) #<__main__.lazyproperty object at 0x0072E8B0>