python函数装饰器用法实例详解
本文实例讲述了python函数装饰器用法。分享给大家供大家参考。具体如下:
装饰器经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
#!coding=utf-8 importtime deftimeit(func): defwrapper(a): start=time.clock() func(1,2) end=time.clock() print'used:',end-start printa returnwrapper @timeit #foo=timeit(foo)完全等价, #使用之后,foo函数就变了,相当于是wrapper了 deffoo(a,b): pass #不带参数的装饰器 #wraper将fn进行装饰,returnwraper,返回的wraper就是装饰之后的fn deftest(func): defwraper(): print"teststart" func() print"endstart" returnwraper @test deffoo(): print"infoo" foo()
输出:
teststart infoo endstart
装饰器修饰带参数的函数:
defparameter_test(func): defwraper(a): print"teststart" func(a) print"endstart" returnwraper @parameter_test defparameter_foo(a): print"parameter_foo:"+a #parameter_foo('hello')
输出:
>>> teststart parameter_foo:hello endstart
装饰器修饰不确定参数个数的函数:
defmuch_test(func): defwraper(*args,**kwargs): print"teststart" func(*args,**kwargs) print"endstart" returnwraper @much_test defmuch1(a): printa @much_test defmuch2(a,b,c,d): printa,b,c,d much1('a') much2(1,2,3,4)
输出:
teststart a endstart teststart 1234 endstart
带参数的装饰器,再包一层就可以了:
deftp(name,age): defmuch_test(func): print'inmuch_test' defwraper(*args,**kwargs): print"teststart" printstr(name),'at:'+str(age) func(*args,**kwargs) print"endstart" returnwraper returnmuch_test @tp('one','10') deftpTest(parameter): printparameter tpTest('python....')
输出:
inmuch_test teststart oneat:10 python.... endstart
classlocker: def__init__(self): print("locker.__init__()shouldbenotcalled.") @staticmethod defacquire(): print("locker.acquire()called.(这是静态方法)") @staticmethod defrelease(): print("locker.release()called.(不需要对象实例") defdeco(cls): '''cls必须实现acquire和release静态方法''' def_deco(func): def__deco(): print("before%scalled[%s]."%(func.__name__,cls)) cls.acquire() try: returnfunc() finally: cls.release() return__deco return_deco @deco(locker) defmyfunc(): print("myfunc()called.") myfunc()
输出:
>>> beforemyfunccalled[__main__.locker]. locker.acquire()called.(这是静态方法) myfunc()called. locker.release()called.(不需要对象实例 >>>
classmylocker: def__init__(self): print("mylocker.__init__()called.") @staticmethod defacquire(): print("mylocker.acquire()called.") @staticmethod defunlock(): print("mylocker.unlock()called.") classlockerex(mylocker): @staticmethod defacquire(): print("lockerex.acquire()called.") @staticmethod defunlock(): print("lockerex.unlock()called.") deflockhelper(cls): '''cls必须实现acquire和release静态方法''' def_deco(func): def__deco(*args,**kwargs): print("before%scalled."%func.__name__) cls.acquire() try: returnfunc(*args,**kwargs) finally: cls.unlock() return__deco return_deco classexample: @lockhelper(mylocker) defmyfunc(self): print("myfunc()called.") @lockhelper(mylocker) @lockhelper(lockerex) defmyfunc2(self,a,b): print("myfunc2()called.") returna+b if__name__=="__main__": a=example() a.myfunc() print(a.myfunc()) print(a.myfunc2(1,2)) print(a.myfunc2(3,4))
输出:
beforemyfunccalled. mylocker.acquire()called. myfunc()called. mylocker.unlock()called. beforemyfunccalled. mylocker.acquire()called. myfunc()called. mylocker.unlock()called. None before__decocalled. mylocker.acquire()called. beforemyfunc2called. lockerex.acquire()called. myfunc2()called. lockerex.unlock()called. mylocker.unlock()called. 3 before__decocalled. mylocker.acquire()called. beforemyfunc2called. lockerex.acquire()called. myfunc2()called. lockerex.unlock()called. mylocker.unlock()called. 7
希望本文所述对大家的Python程序设计有所帮助。