The documentation for functools.partial says that it is "roughly equivalent to":
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords) # line to change
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
If I wanted to implement a version that prepends the additional arguments,
it seems like I'd just have to change the indicated line.
Are there any other features/gotchas that I should be worried about in just copying this code?
Looking at the source code for _functoolsmodule.c
, I don't think there's much to worry about.
The module implementation of partial
handles pickling and repr
, but everything else looks like it works as in the documentation so presumably the reason it is implemented in C is just for efficiency. There is also the fact that it is a type rather than just being a function closure.
Note, however, that in the documentation example, func
, args
and keywords
are purely cosmetic; they are not overridable as they are with actual functools.partial
instances. One alternative would be to subclass functools.partial
:
class rpartial(partial):
def __call__(self, *args, **kwargs):
kw = self.keywords.copy()
kw.update(kwargs)
return self.func(*(args + self.args), **kwargs)
One pitfall is how your partial assignment would handle arbitrary arguments, such as in the following example:
def f(a,b, *args):
pass
Now partially apply f
to the arguments 1 and 2:
g = partial(f, 1, 2)
What is the value of the parameter b
in g
? Is it 1, or is it still awaiting a value? For that matter, what is the value of a
? Put another way, how many, if any, of the supplied arguments should be treated as additional arguments.