Batu Lab NotesPractical developer guides

Bind a stable unit conversion with functools.partial

By Batu ยท English technical notes

Also published in our Blogger archive.

Bind a stable unit conversion with functools.partial

A converter often has one configuration that should be repeated consistently. Here, convert_length accepts a numeric value plus named from_unit and to_unit arguments. Its table expresses each supported unit in metres, so converting 1.25 metres to centimetres calculates 1.25 * 1 / 0.01, producing 125.0.

functools.partial binds the two unit keywords and returns metres_to_centimetres, a callable that now needs only value. This reduces repeated literals at call sites while keeping the underlying calculation in one testable function. The assertions check both a non-zero conversion and the neutral zero input.

This is stable configuration, not an immutable policy: a caller can pass to_unit="m" when calling a partial object, and that later keyword overrides the bound keyword. Wrap the partial in a function with no unit parameters if overriding must be impossible through its public API. Unknown unit labels raise KeyError, and binary floating-point inputs can expose rounding artifacts for values that cannot be represented exactly. Use Decimal if decimal precision is a business requirement.

AI assistance disclosure: This article was prepared with AI assistance.

Example

from functools import partial

UNIT_TO_METRES = {"m": 1.0, "cm": 0.01, "km": 1000.0}


def convert_length(value, *, from_unit, to_unit):
    return value * UNIT_TO_METRES[from_unit] / UNIT_TO_METRES[to_unit]


metres_to_centimetres = partial(
    convert_length,
    from_unit="m",
    to_unit="cm",
)

first = metres_to_centimetres(1.25)
second = metres_to_centimetres(0.0)
assert first == 125.0
assert second == 0.0
print(first)
print(second)

Expected output

125.0
0.0

Source: Python functools.partial documentation.