浅谈Python装饰器-限制函数调用次数的方法

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

浅谈Python装饰器-限制函数调用次数的方法最近有小伙伴留言说自己去面试时遇到公司让写一个装饰器,限制函数每10s调用一次。本篇文章小编就和大家分享一下Python装饰器-限制函数调用次数的方法(10s调用一次),对Python开发感兴趣的小伙伴就随着小编一起来了解一下吧。装饰器分为带参数得装饰器以及不带参数得装饰器。#不带参数的装饰器@dec1@dec2deffunc():...#这个函数声明等价于func=dec1(dec2(func))#带参数的装饰器@dec(some_args)deffunc():...#这个函数声明等价于func=dec(some_args)(func)不带参数的装饰器需要注意的一些细节。1.关于装饰器函数(decorator)本身因此一个装饰器一般对应两个函数,一个是decorator函数,用来进行一些初始化操作处理,一个是decorated_func用来实现对被装饰的函数func的额外处理。并且为了保持对func的引用,decorated_func一般作为decorator的内部函数:defdecorator(func):defdecorator_func()func()returndecorated_funcdecorator函数只在函数声明的时候被调用一次装饰器实际上是语法糖,在声明函数之后就会被调用,产生decorated_func,并把func符号的引用替换为decorated_func。之后每次调用func函数,实际调用的是decorated_func(这个很重要,装饰之后,其实每次调用的是decorated_func)。defdecorator(func):...defdecorated_func():...func(1)...returndecorated_func...#声明时就被调用@decorator...deffunc(x):...printx...decoratorbeingcalled#使用func()函数实际上使用的是decorated_func函数func()1func.__name__'decorated_func'如果要保证返回的decorated_func的函数名与func的函数名相同,应当在decorator函数返回decorated_func之前,加入decorated_func.name=func.name,另外functools模块提供了wraps装饰器,可以完成这一动作。#@wraps(func)的操作相当于#在returndecorated_func之前,执行#decorated_func.__name__=func.__name__#func作为装饰器参数传入,#decorated_func则作为wraps返回的函数的参数传入defdecorator(func):...@wraps(func)...defdecorated_func():...func(1)...returndecorated_func...#声明时就被调用@decorator...deffunc(x):...printx...decoratorbeingcalled#使用func()函数实际上使用的是decorated_func函数func()1func.__name__'func'decorator函数局部变量的妙用因为closure的特性,decorator声明的变量会被decorated_func.func_closure引用,所以调用了decorator方法结束之后,decorator方法的局部变量也不会被回收,因此可以用decorator方法的局部变量作为计数器,缓存等等。值得注意的是,如果要改变变量的值,该变量一定要是可变对象,因此就算是计数器,也应当用列表来实现。并且声明一次函数调用一次decorator函数,所以不同函数的计数器之间互不冲突,例如:#!/usr/bin/envpython#filenamedecorator.pydefdecorator(func):#注意这里使用可变对象a=[0]defdecorated_func(*args,**keyargs):func(*args,**keyargs)#因为闭包是浅拷贝,如果是不可变对象,每次调用完成后符号都会被清空,导致错误a[0]+=1print%shavebingcalled%dtimes%(func.__name__,a[0])returndecorated_func@decoratordeffunc(x):printx@decoratordeftheOtherFunc(x):printx下面我们开始写代码:#coding=UTF-8#!/usr/bin/envpython#filenamedecorator.pyimporttimefromfunctoolsimportwrapsdefdecorator(func):cacheforfunctionresult,whichisimmutablewithfixedargumentsprintinitialcachefor%s%func.__name__cache={}@wraps(func)defdecorated_func(*args,**kwargs):#函数的名称作为keykey=func.__name__result=None#判断是否存在缓存ifkeyincache.keys():(result,updateTime)=cache[key]#过期时间固定为10秒iftime.time()-updateTime10:printlimitcall10s,keyresult=updateTimeelse:printcacheexpired!!!cancallresult=Noneelse:printnocachefor,key#如果过期,或则没有缓存调用方法ifresultisNone:result=func(*args,**kwargs)cache[key]=(result,time.time())returnresultreturndecorated_func@decoratordeffunc(x):print'callfunc'随便测试了下,基本没有问题。fromdecoratorimportfuncinitialcacheforfuncfunc(1)nocacheforfunccallfuncfunc(1)limitcall10sfunc1488082913.239092func(1)cacheexpired!!!cancallcallfuncfunc(1)limitcall10sfunc1488082923.298204func(1)cacheexpired!!!cancallcallfuncfunc(1)limitcall10sfunc1488082935.165979func(1)limitcall10sfunc1488082935.165979以上就是小编给大家分享的Python装饰器-限制函数调用次数的方法(10s调用一次),希望对小伙伴们有所帮助,想要了解更多内容的小伙伴可以登录扣丁学堂官网咨询。

1 / 5
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功