Install with:
pip install better-partial
My library provides both a more ergonomic and expressive way of partially applying functions than functools.partial
. We begin by decorating a function with our partial
operator. Let's consider the following function:
from better_partial import partial, _
# Note that "_" can be imported under a different name if it clashes with your conventions
@partial
def f(a, b, c, d, e):
return a, b, c, d, e
We can then evaluate f
like a standard function:
f(1, 2, 3, 4, 5) # --> (1, 2, 3, 4, 5)
but under the hood, my decorator now enables partial applications of f
. Suppose we wanted to produce a function with all of f
's arguments fixed except for c
. We can accomplish this via the placeholder _
as follows:
g = f(1, 2, _, 4, 5)
g(3) # --> (1, 2, 3, 4, 5)
Alternatively, we might want to produce a function in which only c
is specified. We can accomplish this using ...
:
g = f(..., c=3)
g(1, 2, 4, 5) # --> (1, 2, 3, 4, 5)
...
must be specified as the last positional argument and indicates that all following positional arguments should be treated as placeholders. This means that we can specify a
and d
as follows:
g = f(1, ..., d=4)
g(2, 3, 5) # --> (1, 2, 3, 4, 5)
The functions returned by partial applications are themselves partially applicable:
g = f(..., e=5)
h = g(_, 2, 3, 4)
h(1) # --> (1, 2, 3, 4, 5)
This enables a diversity of ways to partially apply functions. Consider the following equivalent expressions for (1, 2, 3, 4, 5)
:
f(1, 2, 3, 4, 5)
f(_, 2, _, 4, _)(1, 3, 5)
f(1, _, 3, ...)(2, 4, 5)
f(..., a=1, e=5)(_, 3, _)(2, 4)
f(..., e=5)(..., d=4)(1, 2, 3)
f(1, ..., e=5)(2, ..., d=4)(3)
f(..., e=5)(..., d=4)(..., c=3)(..., b=2)(..., a=1)
f(_, _, _, _, _)(1, 2, 3, 4, 5)
f(...)(1, 2, 3, 4, 5)