im trying to access my decorators arguments inside the wrapper function with no luck.
what i have is:
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 = arg开发者_开发问答2 # error
newarg1 = arg1 # working
newarg2 = arg2 # working
return method(*args, **kwargs)
return wrapper
return decorator
and i would use it like a normal decorator
@my_decorator(arg1=True, arg2='a sting or whatever else')
the_function()
i really don't understand why i can't access the decorators arguments.
You can access arg1
and arg2
, but you should not assign to these names, not even with "augmented" assign operators, because this would make them local variables in the inner function. The error message you get shows that you tried to do exactly this (though you did not show your code).
In Python 3, you can work around this problem using
nonlocal arg1, arg2
somewhere in wrapper()
.
It depends on what you do with arg1
and arg2
. Generally, closures work perfectly without extra work. However, if you re-assign them in the inner function, Python assumes it's a local variable and you have to tell it otherwise.
In Python 3, declare nonlocal arg1, arg2
. In Python 2, you have to cheat: Wrap the two into lists (arg1 = [arg1]
in the outer function) and use arg1[0]
in the inner function. If you want an explanation of why this works, either search for Python questions on this topic or refer to the documentation (somewhere in the language reference I believe, I'll search).
Your problem is that wrapper
passes self
to method
. There's no self
. You'd have to take it (and even then, you'd restrict the decorator to methods - why not let self
slip into *args
?).
I fail to see how you read "referenced before assignment" from "global name self
is not defined"...
精彩评论