[BangPypers] Currying in Python 3.0

Jeff Rush jeff at taupro.com
Thu Dec 11 08:11:57 CET 2008


Anand Balachandran Pillai wrote:
> The new functools module in Python provides a neat
> API for doing function currying and doing some other
> FP tricks.

<snip>

> Of course, the above can all be done in Python <3.0 using lambda,
> but functools.partial makes it look neater.

I haven't looked at Python 3.0 yet much to see if they have changed functools
but the functools module exists in Python 2.5.

Don't overlook that the functools.partial function supports keyword arguments,
and that classes are callables so functools.partial can manipulate them as well:

  class GenericWindow:
      def __init__(self, name, width, height, color='white'):
          pass

you can conceptually subclass it without using a class:

  TinyWindow = functools.partial(GenericWindow, width=100, height=40)

and then use it:

  msgwindow = TinyWindow('errors')

It is like default arguments but more flexible in that you can decide on the
defaults at runtime not definition time.

You can also use closures to get some of the same benefits, of parameterizing
code itself:

  def salary_above(amount):

     def wages_test(person):
         return person.salary > amount

     return wages_test

  is_paygrade1 = salary_above(20000)
  is_paygrade2 = salary_above(40000)

  if is_paygrade1(john):
      ...

with functools.partial this would instead be:

  def wages_test(person, amount):
      return person.salary > amount

  is_paygrade1 = functools.partial(wages_test, amount=20000)
  is_paygrade2 = functools.partial(wages_test, amount=40000)

Using partial lets you place the customization away from the function being
customized, in case it isn't your function, unlike closures.  But the closure
is probably faster to execute.

And (pardon my enthusiasm, but early-binding is cool) like the GenericWindow
class example above you can also conceptually create new functions without
declaring functions:

  is_allowed = { # set of allowable headers
      'HTTP_AUTHORIZATION': 1,
      'HTTP_CGI_AUTHORIZATION': 1,
      }.has_key

  if is_allowed('HTTP_AUTHORIZATION'):
      ...

Python is fun to play around with and try to expand your view of what
programming is. ;-)

-Jeff


More information about the BangPypers mailing list