访问装饰器包装函数内部的装饰器参数

时间:2011-02-10 21:31:19

标签: python arguments decorator optional-arguments

我试图在包装函数中访问我的装饰器参数而没有运气。

我拥有的是:

def my_decorator(arg1=False, arg2=None):

    def decorator(method):
        @functools.wraps(method)
        def wrapper(method, *args, **kwargs):
            # do something based on arg1 and arg2
            # accessing one of the two named arguments
            # ends up in a 'referenced before assignment'

            arg1 = arg1 # error
            arg2 = arg2 # error

            newarg1 = arg1 # working
            newarg2 = arg2 # working

            return method(*args, **kwargs)
        return wrapper
    return decorator

我会像普通装饰一样使用它

@my_decorator(arg1=True, arg2='a sting or whatever else')
the_function()

我真的不明白为什么我无法访问装饰器参数。

2 个答案:

答案 0 :(得分:2)

您可以访问arg1arg2,但您不应该分配这些名称,甚至不能使用“增强”赋值运算符,因为这会使它们成为内部函数中的局部变量。您收到的错误消息表明您尝试这样做(尽管您没有显示您的代码)。

在Python 3中,您可以使用

解决此问题
nonlocal arg1, arg2

wrapper()中的某个地方。

答案 1 :(得分:0)

这取决于您对arg1arg2的处理方式。通常,闭合工作完美无需额外工作。但是,如果在内部函数中重新分配它们,Python会假定它是一个局部变量,否则你必须告诉它。

在Python 3中,声明nonlocal arg1, arg2。在Python 2中,你必须作弊:将两个包装到列表中(外部函数中为arg1 = [arg1])并在内部函数中使用arg1[0]。如果你想解释为什么这样做,要么搜索关于这个主题的Python问题,要么参考文档(在我认为的语言参考的某个地方,我会搜索)。

您的问题是wrapperself传递给method。没有self。您必须接受它(即使这样,您也会将装饰器限制为方法 - 为什么不让self进入*args?)。

我没有看到您如何阅读“全局名称self未定义”中的“在分配前引用”...