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

python中的装饰器

时间:2023-03-26 13:10:35 Python

代码环境:python3.6什么是装饰器?装饰器是python的语法糖。它本质上是一个可调用对象,其参数是一个装饰函数。装饰器可以处理装饰后的函数并返回它,或者用另一个函数或对象替换它。装饰器的两种常见用法是不加改变地返回装饰后的函数。这种用法出现在很多pythonweb框架中,比如registry上把url地址映射到http响应的函数上。这是一个简单的例子:defregister(func):#Nonewfunctioninsideprint('runningregister{}'.format(func))returnfunc@registerdefmy_func():print('runningmy_func()')if__name__=="__main__":my_func()用新函数替换装饰函数大多数装饰器通常会在内部定义一个带有闭包结构的函数,并返回它来替换装饰函数。这种用法是最常见的,用于在不修改原有功能的情况下增加额外的功能,比如计算功能的运行时间,输出指定格式的日志等。下面使用装饰器输出函数的运行时间:defrunning_time(func):#里面有一个新的函数defprint_running_time(*args):'''打印函数的运行时间'''t0=time.time()result=func(*args)need_time=time.time()-t0print('新列表生成时间(秒):{:.8f}'.format(need_time))returnresultreturnprint_running_time@running_timedefnew_list(n):'''生成一个新列表'''temp_list=[]forxinrange(n):temp_list.append(x*(x+1))returntemp_listif__name__=="__main__":print('newlistlength:{}'.format(len(new_list(12345))))print('new_list函数的__name__属性:{}'.format(new_list.__name__))print('new_list函数的__doc__属性function:{}'.format(new_list.__doc__))执行结果:runningregister新列表生成时间(秒):0.00250006新列表长度:12345new_list函数的__name__属性:print_running_timenew_list函数的__doc__属性:python执行装饰器时打印函数运行时间从上面的例子中,我们注意到在调用new_list(12345)打印出结果之前,结果列首先输出装饰器中的打印语句,也就是说装饰器导入模块@func时立即执行。functools.wrapsdecorator在上面的结果中,我们还注意到了另一个特点:new_list函数的__name__和__doc__属性被装饰器内部函数的相关属性替换了。所以,我们需要改进上面的例子,使用functools.wraps装饰器将相关属性从func复制到新函数中。改进后的例子如下:fromfunctoolsimportwrapsdefrunning_time(func):#里面有一个新函数@wraps(func)#这里使用wraps装饰器defprint_running_time(*args):'''printfunctionrunningtime'''t0=time.time()result=func(*args)need_time=time.time()-t0print('新列表生成时间(秒):{:.8f}'.format(need_time))returnresultreturnprint_running_time@running_timedefnew_list(n):'''生成一个新列表'''temp_list=[]forxinrange(n):temp_list.append(x*(x+1))returntemp_listif__name__=="__main__":print('新列表长度:{}'.format(len(new_list(12345))))print('new_list函数的__name__属性:{}'.format(new_list.__name__))print('__doc__new_list函数的属性:{}'.format(new_list.__doc__))执行结果:runningregister新列表生成时间(秒):0.00250006新列表长度:12345__name__new_list函数的属性:new_list__doc__attributeofnew_listfunction:generatedAnewlist观察改进后的例子运行结果,new_list函数的相关属性已经恢复正常。