Python The functools Module
The functools module is a toolbox for working with functions.
Fix an argument with partial
partial fills in exp. The new function needs only base.
from functools import partial
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
cube = partial(power, exp=3)
print(square(5))
print(cube(2))Fold a list with reduce
Fold means you combine items one by one. reduce keeps a running result as it goes.
from functools import reduce
numbers = [1, 2, 3, 4]
total = reduce(lambda a, b: a + b, numbers)
product = reduce(lambda a, b: a * b, numbers)
print(total)
print(product)Pick code by type
Dispatch means Python chooses a function for you. singledispatch looks at the first argument type.
from functools import singledispatch
@singledispatch
def label(value):
return f"value: {value}"
@label.register(int)
def _(value):
return f"number: {value}"
print(label(7))
print(label("hi"))Build a number parser
int() takes a base argument. partial fixes base, so the text is the only input left.
from functools import partial
parse_binary = partial(int, base=2)
print(parse_binary("1010"))
print(parse_binary("111"))Tools you met before
wraps keeps a wrapped function's name. lru_cache saves results for repeated calls.
from functools import wraps, lru_cache
# wraps keeps a wrapped function's name.
# lru_cache saves results for repeated calls.Example
from functools import singledispatch, partial
@singledispatch
def format_value(value):
return f"other: {value}"
@format_value.register(int)
def _(value):
return f"int: {value}"
@format_value.register(str)
def _(value):
return f"text: {value} ({len(value)} letters)"
@format_value.register(list)
def _(value):
return f"list of {len(value)} items"
print(format_value(42))
print(format_value("hello"))
print(format_value([1, 2, 3]))
parse_binary = partial(int, base=2)
parse_hex = partial(int, base=16)
print(parse_binary("1010"))
print(parse_hex("ff"))Key points
- Partial function: a new function with some arguments already filled in
- Use partial(func, ...) to fix arguments and reuse the rest later
- Fold: combine a sequence into one value, step by step
- Use reduce(func, sequence) to fold values with a two-argument function
- Dispatch: choose code based on the type of a value
- Use singledispatch to pick a version by the first argument type
- The functools module groups these function tools in one place.
- A plain loop or sum() is often clearer than reduce
In this example, format_value starts as a plain fallback function. The register lines add versions for int, str, and list. Python picks the version that matches each value type. So 42 uses the int version. The word hello uses the str version. The list uses the list version. Then partial builds two number parsers. parse_binary fixes base to 2. parse_hex fixes base to 16. The last prints show 1010 as 10 and ff as 255.
Note
Reach for reduce only when the fold reads well.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
What does partial do?