使用修饰符将变量引入修饰函数namesp

2024-09-29 17:22:16 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个函数,如下所示:

def func(arg1, arg2):
    return arg1 + arg2 + arg3

我想使用传递给decorator的参数引入arg3。这是可能的吗?如果可能的话,怎么做?在

我尝试过这样做,建议here能够将参数传递给装饰器:

^{pr2}$

但我得到了一个错误(可以理解):

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

对于我的应用程序,能够以这种方式定义函数会更好。还有其他的方法,但是接下来需要在每个函数的主体中添加更多的代码。在


Tags: 函数returncodeutilsusersarg3filedropbox
2条回答

你可以那样做

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))

这样你就不需要附加任何名字,你可以申请任意多个装饰师。所以如果你想增加更多的装饰工,那就行了。例如

^{pr2}$

这有点老套,但是这个decorator的实现似乎能满足您的需要。必须使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

相关问题 更多 >

    热门问题