The functools module is intended to contain tools for functional-style programming.
One useful tool in this module is the partial() function.
For programs written in a functional style, you'll sometimes want to
construct variants of existing functions that have some of the
parameters filled in. Consider a Python function f(a, b, c);
you could create a new function g(b, c) that was equivalent to
f(1, b, c). This is called ``partial function application''.
partial takes the arguments
(function, arg1, arg2, ...
kwarg1=value1, kwarg2=value2). The resulting
object is callable, so you can just call it to invoke function
with the filled-in arguments.
Here's a small but realistic example:
import functools
def log (message, subsystem):
"Write the contents of 'message' to the specified subsystem."
print '%s: %s' % (subsystem, message)
...
server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')
Here's another example, from a program that uses PyGTK. Here a context-sensitive pop-up menu is being constructed dynamically. The callback provided for the menu option is a partially applied version of the open_item() method, where the first argument has been provided.
...
class Application:
def open_item(self, path):
...
def init (self):
open_func = functools.partial(self.open_item, item_path)
popup_menu.append( ("Open", open_func, 1) )
Another function in the functools module is the update_wrapper(wrapper, wrapped) function that helps you write well-behaved decorators. update_wrapper() copies the name, module, and docstring attribute to a wrapper function so that tracebacks inside the wrapped function are easier to understand. For example, you might write:
def my_decorator(f):
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
functools.update_wrapper(wrapper, f)
return wrapper
wraps() is a decorator that can be used inside your own decorators to copy the wrapped function's information. An alternate version of the previous example would be:
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
return wrapper
See Also:
See About this document... for information on suggesting changes.