Callbacks, key functions and configured helpers often need a function with some arguments already decided.
partial(func, *args, **kwargs) returns a new callable that calls func with the given arguments pre-filled, followed by whatever you pass later:
from functools import partial
parse_hex = partial(int, base=16)
parse_hex("ff") # 255Positional arguments are prepended; keyword arguments are merged, and keywords supplied at call time override the stored ones.
Typical uses:
- Passing a configured function where a one-argument callable is expected:
map(partial(round, ndigits=2), values),sorted(items, key=partial(distance, origin)). - Callbacks in GUIs,
threading.Thread(target=...),atexit.registeror event systems, where you need to bind arguments now and call later. - Specialising general functions:
log_error = partial(log, level="ERROR").
A partial object exposes .func, .args and .keywords, and has a readable repr, which a lambda doesn't. It also pickles (if the function does), so it works with multiprocessing where lambdas fail.
Compared with lambda x: int(x, base=16), partial binds values immediately, whereas a lambda looks variables up when called. That avoids the classic late-binding bug in loops that create callbacks.
Example
from functools import partial
parse_hex = partial(int, base=16)
print(parse_hex("ff"), parse_hex("10")) # 255 16
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
print(list(map(square, [1, 2, 3]))) # [1, 4, 9]
print(square(3, exp=3)) # 27 (call-time keyword wins)
print(square.func.__name__, square.keywords) # power {'exp': 2}
lambdas = [lambda: i for i in range(3)]
partials = [partial(int, i) for i in range(3)]
print([f() for f in lambdas]) # [2, 2, 2] -- late binding
print([f() for f in partials]) # [0, 1, 2]Remember
partial(f, *args, **kw)returns f with some arguments fixed- Values are bound immediately, avoiding lambda late-binding bugs
- Partials are introspectable and picklable
Watch out for
- Pre-filling a positional argument that isn't the first one; use a keyword argument instead.