装饰器的作业:在不更改原功能函数内部代码,并且不改变调用方法的情况下为源代码添加新的功能
1、普通装饰器
装饰器原理:将被装饰的函数当做一个参数传到装饰器中,并且让被装饰的函数名指向装饰器内部的函数,在
装饰器的内部函数中用来接收到的参数再调用被装饰器的函数。
def work(func): #接收 被装饰的函数
def warp(): func() #调用 return warp @work #相当于 func=work(func) def func(): print("装饰器") func()
2、装饰带参数的函数
def work(func): def warp(a,b): func(a,b) return warp @work def func(a,b): print("数据:{0}".format(a+b)) func(1,2)#输出 数据:3
3、通用装饰器
def work(func): def warp(*args,**kwargs): func(*args,**kwargs) return warp @work def func(a,b): print("数据:{0}".format(a+b)) func(1,2)#输出 数据:3
def work(func): def warp(*args,**kwargs): res=func(*args,**kwargs) return res #返回原功能函数的调用结果 return warp @work def func(a,b): print(f"装饰器{a+b}") return 'func' print(func(1,3)) #输出: 装饰器4 func
4、装饰器装饰类
5、装饰器传参数
def work(num): #接收装饰器的参数 def work1(func):#接收 被装饰器的函数 def warp(*args, **kwargs):#接收 被装饰器函数的参数 print(f"装饰器的参数{num}") res = func(*args, **kwargs) return res # 返回原功能函数的调用结果 return warp return work1 @work(10) #func=work(10)(func) def func(a,b): print(f"装饰器{a+b}") return 'func' print(func(1,3)) #输出:装饰器的参数10 装饰器4 func
6、多个装饰器装饰同一个函数
def work2(func): def warp(*args, **kwargs): print(f"work2---start----") res = func(*args, **kwargs) print(f"work2---end----") return warp def work1(func): def warp(*args, **kwargs): print(f"work1---start----") res = func(*args, **kwargs) print(f"work1---end----") return warp @work2 @work1 #func=work2(work1(func)) def func(a,b): print(f"装饰器{a+b}") func(1,3) """ work2---start---- work1---start---- 装饰器4 work1---end---- work2---end---- """
7、类实现装饰器
如果要把类当做一个装饰器来用:
1、首先在__init__方法中,把装饰器的函数赋值给一个实例属性
2、然后在类里面实现一个__call__方法,在call方法中调用原来的函数
class Test: def __init__(self,func): self.func=func def __call__(self, *args, **kwargs): print("类装饰器") self.func(self, *args, **kwargs)
7、函数缓存装饰器
functools.wraps():一般用来消除装饰之后的副作用(让被装饰的函数保留原有的属性)
functools.lru_cache: 缓存装饰器
maxsize参数设置缓存内存占用上限,其值应当设为2的冥,值为None时表示没有上限。
typed参数设置表示不同参数类型的调用是否分别缓存;如果设置为True,那fibonacci(5)和fibonacci(5.0)将分别缓存
from functools import lru_cache dic={"count":0} @lru_cache(maxsize=None) def func(n): dic["count"] +=1 if n ==1 or n ==2: return 1 else: res=func(n-1)+func(n-2) return res res=func(200) print(res) print(dic)