写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数。但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函数才能返回里面装饰器(就是接收函数的函数)。以前一篇为例,可以这样改进:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
def opt_arguments(func): def
meta_wrapper( * args, * * kwargs): if
len (args) = =
1 and callable (args[ 0 ]): return
func(args[ 0 ]) else : def
meta_func(inner_func): return
func(inner_func, * args, * * kwargs) return
meta_func return
meta_wrapper @opt_arguments def annotation(func, * * annotations): """ A decorator to collect all named args to function.__namedargs__, all anonymous args to function.__unnamedargs__, decorator‘s args to function.__annotations__. """ @functools .wraps(func) def
func_wrapper( * args, * * kwargs): argspec =
inspect.getargspec(func) namedargs =
inspect.getcallargs(func, * args, * * kwargs) # def foo(a, b=0, *c, **d): pass # foo(1, b=2, c=3, d=4) will convert c=3 to namedargs. unnamedargs =
namedargs.pop(argspec.varargs, ()) namedargs.update(namedargs.pop(argspec.keywords, {})) func_wrapper.__namedargs__ =
namedargs func_wrapper.__unnamedargs__ =
unnamedargs func_wrapper.__annotations__ =
annotations func( * args, * * kwargs) return
func_wrapper |
这样得到的annotation可以无参数使用:
Python: 无参数的函数装饰器,布布扣,bubuko.com
原文:http://www.cnblogs.com/codingmylife/p/3641494.html