假设我有一个看起来像这样的函数:
def func(arg1, arg2):
return arg1 + arg2 + arg3
我想使用传递给装饰器的参数引入arg3
。这是可能的,如果可以的话,会怎样做?
我已经尝试了这个,建议here能够将参数传递给装饰器:
from functools import wraps
def addarg(arg):
def decorate(func):
arg3 = arg
@wraps(func)
def wrapped(*args):
return func(*args)
return wrapped
return decorate
@addarg(3)
def func(arg1, arg2):
return arg1 + arg2 + arg3
if __name__ == "__main__":
print(func(1, 2))
但是我得到了这个错误(可以理解):
Traceback (most recent call last):
File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 19, in <module>
print(func(1, 2))
File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 9, in wrapped
return func(*args)
File "C:/Users/pbreach/Dropbox/FIDS/PhD/Code/anemi3/utils.py", line 16, in func
return arg1 + arg2 + arg3
NameError: name 'arg3' is not defined
对于我的应用程序,能够以这种方式定义函数会更好。还有其他方法,但是必须将更多代码添加到每个函数的主体中。
答案 0 :(得分:0)
你可以这样做
DECLARE @ResultAmount int = 243
SELECT @ResultAmount - (@ResultAmount%50)
这样您就不会附加任何名称,您可以根据需要应用尽可能多的装饰器。因此,如果你想添加更多装饰器,它将起作用。例如
from functools import wraps
def addarg(arg):
def decorate(func):
@wraps(func)
def wrapped(*args):
return func(*args, arg)
return wrapped
return decorate
@addarg(3)
def func(arg1, arg2, *args):
return arg1 + arg2 + sum(args)
if __name__ == "__main__":
print(func(1, 2))
答案 1 :(得分:0)
这有点在黑客方面,但装饰者的这个实施似乎做你想要的。必须使arg3
变量显示为全局变量,因为它在从func()
的定义生成的字节代码中被引用为一个,因此它不是真正被认为是函数参数 - 但是它没有'在这种情况下似乎很重要。
from functools import wraps
def addarg(arg):
def decorate(func):
@wraps(func)
def wrapped(*args):
global_vars, local_vars = {'func': func, 'args': args}, {}
func.__globals__.update(arg3=arg)
exec('_result = func(*args)', global_vars, local_vars)
return local_vars['_result']
return wrapped
return decorate
@addarg(3)
def func(arg1, arg2):
return arg1 + arg2 + arg3
if __name__ == "__main__":
print(func(1, 2)) # -> 6