Batu Lab NotesPractical developer guides

Dispatch a formatter for text and integer values

By Batu ยท English technical notes

Also published in our Blogger archive.

Dispatch a formatter for text and integer values

By Batu

functools.singledispatch selects an implementation from the type of its first argument. This recipe defines one public format_value() function, then registers dedicated handlers for str and int. Calling it with "draft" returns a quoted text label; calling it with 42 returns a zero-padded integer label. The common call site does not need an isinstance() chain.

The base function deliberately raises TypeError. That turns an unsupported value, such as a float, into a clear failure instead of silently choosing an arbitrary representation. bool needs special attention: Python documents bool as a subclass of int, so format_value(True) would use the integer handler unless a bool handler is registered. This example avoids making a claim about Boolean formatting by only passing the two supported input types.

Dispatch is based on runtime type and walks the method-resolution order when an exact registration is absent. It does not dispatch from the type of a second argument, and it is not a schema validator. If strings need escaping for HTML, SQL, or a shell, add an encoder designed for that destination; these decorative return strings provide no such protection.

AI assistance was used to draft this article.

from functools import singledispatch


@singledispatch
def format_value(value):
    raise TypeError(f"unsupported value type: {type(value).__name__}")


@format_value.register
def _(value: str) -> str:
    return f'text="{value}"'


@format_value.register
def _(value: int) -> str:
    return f"integer={value:04d}"


text_result = format_value("draft")
integer_result = format_value(42)

assert text_result == 'text="draft"'
assert integer_result == "integer=0042"
print(text_result)
print(integer_result)

Expected stdout:

text="draft"
integer=0042

Sources