[Python-Dev] Partial function application 'from the right'

Ben North ben at redfrontdoor.org
Thu Jan 29 15:12:02 CET 2009


Hi,

I find 'functools.partial' useful, but occasionally I'm unable to use it
because it lacks a 'from the right' version.  E.g., to create a function
which splits a string on commas, you can't say

   # Won't work when called:
   split_comma = partial(str.split, sep = ',')

and to create a 'log to base 10' function, you can't say

   # Won't work when called:
   log_10 = partial(math.log, base = 10.0)

because str.split and math.log don't take keyword arguments.

PEP-309, which introduces functools.partial, mentions

   For completeness, another object that appends partial arguments after
   those supplied in the function call (maybe called rightcurry) has
   been suggested.

'Completeness' by itself doesn't seem to have been a compelling reason
to introduce this feature, but the above cases show that it would be of
real use.

I've created a patch which adds a 'partial_right' function.  The two
examples above:

   >>> import functools, math

   >>> split_comma = functools.partial_right(str.split, ',')
   >>> split_comma('a,b,c')
   ['a', 'b', 'c']

   >>> log_10 = functools.partial_right(math.log, 10.0)
   >>> log_10(100.0)
   2.0

and a general illustrative one:

   >>> def all_args(*args): return args
   ...
   >>> functools.partial_right(all_args, 1, 2)(3, 4)
   (3, 4, 1, 2)

I was prompted to look at this by a recent message on python-dev:

Xavier Morel <catch-all at masklinn.net>, Thu, 22 Jan 2009 14:44:41 +0100:
> [...] drop(iterable, n) has to be written islice(iterable, n, None)
> (and of course the naming isn't ideal), and you can't really use
> functools.partial since the iterator is the first argument (unless
> there's a way to partially apply only the tail args without kwargs).

Xavier's case becomes:

   >>> import functools, itertools
   >>> drop = functools.partial_right(itertools.islice, None, None)
   >>> list(drop(range(10), 5))
   [5, 6, 7, 8, 9]

The patch adds a 'from_right' member to partial objects, which can be
True for the new from-the-right behaviour, or False for the existing
from-the-left behaviour.  It's quite small, only c.40 lines, plus a
c.70-line change to test_functools.py.  I imagine a documention patch
would be c.20 lines.

Would there be any interest in this?

Ben.


More information about the Python-Dev mailing list