There is a tool in the functools library named partial.
functools.partial allows us to specify some of the inputs a function without specifying all of them.
You can transform ...
funky_function(x1, x2, x3, x4, x5)
into something like...
funky_function(1, 2, x3, x4, x5)
That is...
- Input argument
x1gets assigned the number1 - Input argument
x2gets assigned the number2 - Inputs
x3,x4,x5are still not assigned anything.
from functools import *
from inspect import *
def funky_function(x1, x2, x3, x4, x5, /):
return ", ".join(" ".join(str(x).split()) for x in [x1, x2, x3, x4, x5])
funky_function = partial(funky_function, 1, 2)
result = funky_function(3, 4, 5)
print("return value from `funky_function(3, 4, 5)` is:", result)
print("signature of `funky_function` is:", signature(funky_function))
My question is, how do we make a decorator?
@partialize(1, 2)
def funky_function(x1, x2, x3, x4, x5, /):
return ", ".join(" ".join(str(x).split()) for x in [x1, x2, x3, x4, x5])
result = funky_function(3, 4, 5)
Look at the function signature below of partial.partial(func):
functools.partial(func, /, *args, **keywords)
The function is the left and the arguments on the right.
The following two pieces of code are equivalent:
@decorate(1, 2)
def f():
pass
###################################
def f():
pass
f = decorate(1, 2)(f)
So, partial is not a good decorator if you want to enter arguments first, and enter the function second.
How do we make a decorator which takes in the arguments first, and later accepts the function to-be-decorated?