其实@只是个语法糖, 可以翻译成
如果只是在被装饰的函数之前加入一些功能,装饰器函数不用设计成嵌套的,函数末尾返回被装饰的函数即可,这种用法不太常见。例如:
1 2 3 4 5 6 7 8 9 10
| registry = []
def register(func): print('running register (%s)' % func) registery.append(func) return func
@register def f1(): print('running f1()')
|
如果要修改被装饰的函数的功能,装饰器函数要定义成嵌套函数,并且返回内嵌套函数。例如:
1 2 3 4 5 6 7 8 9 10 11 12
| def clock(func): def clocked(*args): t0 = time.perf_counter() result = func(*args) ecapsed = time.perf_counter() - t0 print('ecapsed=%f' % ecapsed) return result return clocked
@clock def f1(): print('running f1()')
|
还有高级的用法,生成装饰器的工厂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DEFAULT_FMT= '[{elapsed: 0.8f}s]{name}({args})->{result}' def clock(fmt=DEFAULT_FMT): def decorate(func): def clocked(*_args): t0 = time.time() _result = func(*_args) elapsed = time.time() - t0 nmae = func.__name__ args = ','.join(repr(arg) for arg in _args) result = repr(_result) print(fmt.format(**locals())) return _result return clocked return decorate
if __name__ == '__main__': @clock() def snooze(seconds): time.sleep(seconds)
|
装饰器可以叠放
相当于
参考