More intuitive partial function application in Python

87
More intuitive partial function application in Python

Install with:

pip install better-partial

I find functools.partial unintuitive so I coded up a better version. Let’s play around with it. You apply it as a decorator to your functions:

import better_partial as bp

@bp.partial
def some_operation(x, p1, p2):
  return (x + p1) * p2

On the surface nothing really changes. some_operation behaves just like a normal function when you pass it values

some_operation(1, 2, 3)  # --> 9

but under the hood my partial decorator is working all kinds of magic. Imagine you need to pass a function of x to some other part of your codebase and some_operation, with a particular setting of p1=10 and p2=20, fits the bill. In order to make this work, you’d have to wrap some_operation like this:

func = lambda x: some_operation(x, 10, 20)

or this

def func(x):
  return some_operation(x, 10, 20)

The bp.partial decorator makes this a bit nicer. By supplying a bp._ placeholder for any argument in some_operation we can produce a new function where the variables replaced by bp._ are omitted:

func = some_operation(bp._, 10, 20)
func(x) == some_operation(x, 10, 20)  # --> True

You can replace any positional arguments with bp._ to perform partial function applications

@bp.partial
def f(a, b, c, d, e):
  return a + b + c + d + e
  
g = f(bp._, 0, bp._, 0, bp._)
g(1, 3, 5)  # --> 1 + 0 + 3 + 0 + 5

The functions produced by these partial applications also support further partial application. Consider using the g from above again:

h = g(1, bp._, bp._)
h(3, 5)  # --> 1 + 0 + 3 + 0 + 5

This is great if you want to omit a few parameters and specify the rest, but what if it’s the other way around? You just want to fix the values of a few parameters. better_partial lets you do this. Consider f from above and suppose that we want to fix c=5 and a=7, you can do this too:

g = f(..., c=5, a=7)

g(0, 0, 0)  # --> 7 + 0 + 5 + 0 + 0
g(0, 0, 0) == f(7, 0, 5, 0, 0) == f(7, bp._, 5, bp._, bp._)(0, 0, 0)  # --> True

better_partial lets you use the ... sentenel to indicate that you only want to specify the values of what follows.

An easy way to appreciate the flexibility and power of the partial operator is to see the variety of ways you can evaluate functions with it. Using the definition of f from above, all of the following lines are equivalent:

f(1,2,3,4,5)
f(b

Read More

Vanic
WRITTEN BY

Vanic

β€œSimplicity, patience, compassion.
These three are your greatest treasures.
Simple in actions and thoughts, you return to the source of being.
Patient with both friends and enemies,
you accord with the way things are.
Compassionate toward yourself,
you reconcile all beings in the world.”
― Lao Tzu, Tao Te Ching