Bind a stable unit conversion with functools.partial

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.

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic