From the tutorials I have read so far about passing arguments to the decorator, they all mention how a decorated function such as :
@decorator_with_args(arg)
def foo(*args, **kwargs):
pass
translates to:
foo = decorator_with_args(arg)(foo)
or
def my_decorator(arg):
def inner_decorator(f):
def wrapped(*args, **kwargs):
print('before function')
response = f(*args, **kwargs)
print('after function')
return response
print('decorating', f, 'with argument', arg)
return wrapped
return inner_decorator
@my_decorator('foo')
def my_function(a, b):
print('in function')
return a + b
would be equivalent to
my_function = my_decorator('foo')(my_function)
The examples are correct indeed, but isn't the second approach of passing our function to the decorator and assigning to a variable more robust, as here we can change the argument of the decorator as much as we want, such as my_function=my_decorator('foo1')(my_function)
or another_function=my_decorator('foo3')(my_function)
while in the first case the argument always seems to be 'foo' unless for different calls we go back and update the @my_decorator
argument or, redefine the function so as our decorator can take different arguments such as:
@my_decorator('foo2')
def my_function(a, b):
print('in function')
return a + b
@my_decorator('foo5')
def another_function(a, b):
print('in function')
return a + b
This behavior is especially noticeable when importing a decorated function from another module, which calls the function with the default decorator argument without giving the ability to modify.
Please correct me if there is something I am missing. Thanks.
unless for different calls we go back and update the
@my_decorator
argument
Well, you don't do that. That's not a job for a decorator then. A decorator alters the behaviour of a function, and does so while being reusable. I.e. you use a decorator when you want to add the same kind of behaviour to multiple functions, without needing to add the code for that behaviour into each function individually.
In the end, you're composing a function which behaves a certain way. And you simply don't go around redefining functions all the time. You define a function once, and then you call it multiple times. If you need the function to behave differently every time, necessitating you to redefine the function all the time, well, that's not a sane function then.
You decorate the function once, and that function then behaves in a specific way—as a combination of decorator + original function—and you may pass some arguments to that decorator at definition time to make it alter its behaviour in some way, but then this definition should not be redefined all the time, or you basically have no idea how your function will behave at any particular point in time.