装饰器能在运行时与lambda表达式一起工作吗?
def attrs(**kwds):
def decorate(f):
for k in kwds:
setattr(f, k, kwds[k])
return f
return decorate
@attrs(argument_types=(int, int,), returns=int)
def add(a, b):
return a + b
在这里,我需要add()函数能够显示它可以接受的参数类型。可是,我能在运行时做到这一点吗?
ladd=[]
for x in range(0,10):
@attrs(argument_types=int, returns=int,default_parameter1 = x)
exp = lambda : add(a,x)
ladd.append(exp)
或者
ladd=[]
for x in range(0,10):
@attrs(argument_types=int, returns=int,default_parameter1 = x)
addx = functools.partial(add, 2)
ladd.append(addx)
我需要这些函数能够在运行时生成,并且可以绑定“装饰器”参数。
好吧,这里是错误信息,我觉得上面的代码可能无法工作,但我从来没有试过把它粘贴到python里测试一下……
>>> ladd=[]
>>> for x in range(0,10):
... @attrs(argument_types=int, returns=int,default_parameter1 = x)
... exp = lambda : add(a,x)
File "<stdin>", line 3
exp = lambda : add(a,x)
^
SyntaxError: invalid syntax
>>> ladd.append(exp)
File "<stdin>", line 1
ladd.append(exp)
^
IndentationError: unexpected indent
>>>
2 个回答
13
这个@
的写法其实是为了让我们更方便地使用装饰器,它的作用就是把下一个函数作为参数传给装饰器。也就是说,
@deco
def func(): pass
和下面的写法是一样的:
def func(): pass
func = deco(func)
所以你想要的其实就是:
ladd=[]
for x in range(0,10):
deco = attrs(argument_types=int, returns=int,default_parameter1 = x)
addx = functools.partial(add, 2)
# append the "decorated" function
ladd.append(deco(addx))
19
装饰器的语法其实就是一种语法上的简化,虽然它能引导人们思考一些有趣的方向。
@expr
def f(...):
...
这和下面的内容是一样的
def f(...):
...
f = expr(f)
所以你可以直接使用 attrs(argument_types=..., ...)(lambda: ...)
。