Python Decorator with arguments called only once

Please consider the following simplified example:

permitted = True
class is_allowed(object):
    def __init__(self, some_arg):
        # this is actually needed in the complete code
        self.some_arg = some_arg

    def __call__(self, f):
        if permitted == False:
            raise Exception("not authenticated to do that")
        def wrapped_f(*args, **kwargs):
            f(*args, **kwargs)
        return wrapped_f

@is_allowed("blah")
def print_hi():
    print("hi")

print_hi()
permitted = False
print_hi()

      

I guess the problem is that the decorator is only called once when the print_hi () function is defined. Because of this, changing the global variable has no effect. Is there a way to get around this behavior?

+3


source to share


1 answer


Move the check inside wrapped_f

def __call__(self, f):
    def wrapped_f(*args, **kwargs):
        if not permitted:
            raise Exception("not authenticated to do that")
        f(*args, **kwargs)
    return wrapped_f

      



Outside, wrapped_f

it is checked when the function is created. Internally, it becomes part of the body of the new callee, which means it will be checked every time there is a call.

You want to understand what wrapped_f

will be called instead print_hi

, so you want some behavior to be included in a function to get inside that.

+5


source







All Articles