I don't think my_decorator
is a very descriptive name, but maybe that's just part of the assignment. Also, f
isn't a very descriptive name for the function you are decorating.
I did my own test:
>>> @my_decorator(2)
... def here(*args):
... print args
...
>>> here(4, 5)
>>>
Do you know why it doesn't print anything? It's because you have if
and elif
in wrapped_f
, but one argument to my_decorator
and two arguments to here
doesn't match either of your conditions, so wrapped_f
doesn't know what to do. To be safe, it does not call the function and just returns None
. That always happens when you don't tell a function what to return: it returns None
. My question is, why do you have those conditions? I would change that function to:
def wrapped_f(*func_args):
return f(*(deco_args+func_args))
Your code really has only four lines of reviewable code, so I will just suggest a new (not necessarily better) way:
from functools import partial
class MyDecorator:
def __init__(self, *args):
self.args = args
def __call__(self, func):
return partial(func, *self.args)
functools.partial
takes a function and any other arguments and returns a callable object that, when called, calls the function with the original arguments and whatever other arguments are given. Our decorator is called with 2
for my above example, so it sets self.args
to (2,)
. When our MyDecorator
object is called (with here
as an argument), the __call__
method is executed and we return a partial
object with that function and the arguments we got earlier. Therefore, when the result is called with more arguments, it calls the function with the arguments originally given to the decorator as well as the arguments being given currently. You can see that partial
is very similar to your decorator. We just needed to make it decorator-compatible.
Edit: As mentioned by @JoeWallis in the comments, you could still use partial()
in nested functions similar to yours:
def my_decorator(*deco_args):
def wrap(f):
return partial(f, *deco_args)
return wrap
func_args
sometimes precededeco_args
and sometimesfunc_args
followdeco_args
? Perhaps you should calculate2 ** 4
instead of4 ** 2
? \$\endgroup\$