在我理解看来,装饰器就是增强一个函数的附加功能,而不改变该函数的所以实现 比如说:我们想对 一个加法函数,做一个增强,就是额外打印输出一些信息
>>> def add(x,y): >>> return x + y 实现1: >>> def logger(fn): >>> print('begin') >>> x = fn(4,5) >>> print('end') >>> return x >>> print(logger(add)) begin end 9 这个函数看似增强的一些打印信息,但是没法传入参数,就有问题了,不通用 实现2:解决传参问题 >>> def logger(fn,*args,**kwargs): >>> print('begin') >>> x = fn(*args,**kwargs) >>> print('end') >>> return x >>> print(logger(add,5,60)) begin end 65 实现3:将这个函数柯里化 >>> def logger(fn): >>> def _logger(*args,**kwargs): >>> print('begin') >>> ret = fn(*args,**kwargs) >>> print('end') >>> return ret >>> return _logger >>> add = logger(add) >>> print(add(x=5, y=10)) begin end 15 实现4: 使用装饰器语法糖 >>> def logger(fn): >>> def _logger(*args,**kwargs): >>> print('begin') >>> ret = fn(*args,**kwargs) >>> print('end') >>> return ret >>> return _logger >>> @logger #等价于 add = logger(add) >>> def add(x,y): >>> return x + y >>> print(40,50) begin end 90@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
import functools,datetime,time def logger(duration, func = lambda name, duration: print('{} took {}s'.format(name, duration))): def _logger(fn): @functools.wraps(fn) def wrapper(*args,**kwargs): start = datetime.datetime.now() ret = fn(*args,**kwargs) delta = (datetime.datetime.now() - start).total_seconds() if delta > duration: func(fn.__name__, duration) return ret return wrapper return _logger @logger(5) # add = logger(5)(add) def add(x,y): 'this is a add function' time.sleep(1) return x + y print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__,add.__doc__, sep='\n') 输出: 11 add <function add at 0x1033fca60> {'__wrapped__': <function add at 0x1033fca60>} this is a add function