当前位置: 首页 > 后端技术 > Python

Python——装饰器

时间:2023-03-25 22:52:24 Python

1.装饰器简介装饰器本质上是一个闭包函数,它允许其他函数在不更改任何代码的情况下添加额外的功能。装饰器的返回值也是一个函数。闭包函数1)必须是嵌套函数,即在外层函数中定义了一个内层函数;2)内层函数引用外层函数作用域内的变量(注意:不是全局的);3)外层函数的返回值是内层函数对函数的引用;4)检查函数是否为闭包函数:function.__closure__,是闭包,返回cell,不是闭包,返回None;function1)什么是函数:有组织的,可重用的,使用2)函数的优点:函数可以提高应用程序模块化和代码重用;3)函数定义:使用def关键字;deffunc():print("Hello,World!")4)函数参数:根据函数的定义和调用,函数的参数有不同的概念;定义时:持仓参数、默认参数、变长参数;deffunc(a,b=0,*args,**kwargs):print(f"位置参数:{a}")print(f"默认参数:{b}")print(f"可变长度参数:元组{args},dictionary{kwargs}")*调用时:必传参数(必传),关键字参数(可传可不传),变长参数(可传可不传);```Pythonfunc("Hello")#"Hello">>afunc("Hello",b=1)#"Hello">>a,1>>bfunc("Hello",2)#"Hello">>a,2>>bfunc("Hello",2,3,c="World")#"Hello">>a,2>>b,3>>*args,c="World">>**kwargs```5)匿名函数:使用`lambda`关键字,只是一个表达式,不是代码块,逻辑有限;```Pythonadd=lambdaa,b:a+b```6)变量作用域:LEGB;*L:Local,局部作用域;*E:Enclosing,Infunctionsoutsidetheclosurefunction;*G:global,全局作用域;*B:卜ilt-in,内置作用域;7)关于函数的几个概念;*函数是变量:函数可以作为参数或返回值;*高阶函数:以函数为参数或返回值的函数,内置Function`map()`、`filter()`、`reduce()`在`functools`包中;*嵌套函数:函数定义在函数中;*嵌套函数中变量的生命周期:一般情况下,一个函数运行结束后,会回收该函数的所有局部对象,释放内存,但闭包是一种特例。在闭包中,如果外层函数结束,外层函数作用域内的临时变量被内层函数调用,外层函数会将变量绑定到内层函数,然后结束;2.装饰器要满足条件,为被装饰的函数增加新的功能;装饰函数的代码不能更改;装饰函数的调用方式不能改变;3、装饰器的应用场景,插入日志;性能测试;事务处理;缓存、权限验证;4.装饰器固定格式format1defdecorator(func):#内层函数嵌套在装饰器函数中definner(*args,**kwargs):"""somethingbeforefunc"""f=func(*args,**kwargs)#内层函数inner在外层函数装饰器的范围内调用变量func"""somethingafterfunc"""returnfreturninner#外层函数装饰器的返回值是inner(对innerfunctioninner)Format2fromfunctoolsimportwrapsdefdecorator(func):@wrapsdefwrapper(*args,**kwargs):returnfunc(*args,**kwargs)returnwrapper5,装饰器的进化会显式通过装饰函数给装饰器,装饰函数没有参数,没有返回值;importtimedeffunc():print("I'mfunc.")deftimer(f):definner():start=time.time()f()end=time.time()print(end-start)returninnerfunc=timer(func)#将函数func作为参数传递给定时器装饰器,并将返回结果赋值给变量funcfunc()#func(),即执行完func后,被修饰的函数会放在下一行语法糖上。装饰函数没有参数,也没有返回值;importtimedeftimer(f):definner():start=time.time()f()end=time.time()print(end-start)returninner@timer#@timer称为语法糖,相当于func=timer(func)deffunc():print("I'mfunc.")func()将修饰函数放在语法糖的下一行。装饰函数有1个参数,没有返回值;importtimedeftimer(f):definner(i):start=time.time()f(i)end=time.time()打印(结束-开始)returninner@timerdeffunc(x):print(x)func("Hello,World!")将装饰函数放在语法糖的下一行,并且是装饰函数有2个参数,没有返回值;导入timedeftimer(f):definner(*args,**kwargs):start=time.time()f(*args,**kwargs)end=time.time()print(end-start)returninner@timerdeffunc(x,y):print(f"第一个参数是{x},第二个是{y}。")func(2,24)将装饰函数放在句法糖的下一行,装饰函数接受多个参数并返回一个值;importtimedeftimer(f):definner(*args,**kwargs):start=time.time()r=f(*args,**kwargs)end=time.time()print(end-start)returnrreturninner@timerdeffunc(x,y,z=3):print(f"参数是{}、{}和{}.")return'Over'func(1,2,z=3)print(func(1,2,z=3))一个带参数的装饰器,被装饰的函数没有参数也没有返回值;defouter(flag):defdecorator(f):definner(*args,**kwargs):ifflag:print("Aheadfunc")r=f(*args,**kwargs)ifflag:print("func")returnrreturninnerreturndecorator@outer(True)deffunc():print("Hello,World!")func()多个装饰器装饰同一个函数,被装饰的函数无参数,无返回值;defdecorator1(f):definner():print('Decorator1,beforef')f()print('Decorator1,afterf')returninnerdefdecorator2(f):definner():print('Decorator2,beforef')f()print('Decorator2,afterf')returninner@decorator2@decorator1deffunc():print("I'mfunc.")6.装饰器总结Python中有4种装饰器:函数装饰功能,功能装饰类,类装饰函数,类装饰类;函数装饰函数:将函数作为参数传递给装饰器函数;defdecorator(f):definner(*args,**kwargs):print(f"函数名:{f.__name__}")r=f(*args,**kwargs)returnrreturninner@decorator#@decorator相当于addition=decorator(addition)defaddition(x,y):returnx+yprint(addition(3,7))函数装饰类:该类作为参数传入装饰器函数;defdecorator(cls):definner(*args,**kwargs):print(f"classname:{cls.__name__}")returncls(*args,**kwargs)returninner@decorator#@decorator是等价的toFunc=decorator(Func)classFunc:def__init__(self,item):self.item=itemdeffunc(self):print(f"self.a={self.a}")f=Func('你好,World!')f.func()类装饰函数:该函数作为参数传入装饰器类;classDecorator:def__init__(self,f):self.f=fdef__call__(self,item):print(f"函数名:{self.f.__name__}")returnself.f(item)@Decorator#@Decorator等同于func=Decorator(func).__call__deffunc(i):returniprint(func("Hello,World!"))类装饰类:该类作为参数传入装饰器类;类装饰器:def__init__(self,cls):self.cls=clsdef__call__(self,item):print(f"classname:{self.cls.__name__}")returnself.cls(item)@Decorator#@Decorator等价于Func=Decorator(Func).__call__class函数:def__init__(self,v):self.v=vdeffunc(self):print(self.v)f=Func("Hello,World!")f.func()