【发布时间】:2017-01-28 17:35:48
【问题描述】:
假设我有一个看起来像这样的函数:
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
对于我的应用程序,能够以这种方式定义函数会更好。还有其他方法,但必须在每个函数的主体中添加更多代码。
【问题讨论】:
-
为什么你想这样做?您要解决的实际问题是什么?对我来说,这似乎是一个无法阅读代码的秘诀。
-
密切相关:Getting the block of commands that are to be executed in the with statement;那里的解决方案也适用于装饰器,因为
arg3只会作为全局变量被发现。 -
我试图让用户将常微分方程系统定义为一系列函数,以类似于现有软件的方式进行集成。
-
装饰器会引入一些切片对象或常量用于 numpy 数组,这些数组指定特定元素或维度来子集数组,而不是在有意义的情况下对切片或元素进行硬编码。但你是对的,可能有更好的方法来做到这一点。
标签: python function namespaces python-decorators