mercredi 29 septembre 2021

Templated object generation in python

What is a good design pattern to implement templated object generation (not sure that's the name) in python?

By that, I mean having a function such as:

from typing import TypeVar

T = TypeVar('T')

def mk_templated_obj_factory(template: T) -> Callable[..., T]:
    """Returns a f(**kwargs) function that returns an object of type T created by a template of the same type."""

Python has templated strings. Something like `"this {is} a {template}".format' would be how one could achieve the above. If we want to get a "proper" function that has a signature (useful for a user so they know what arguments they need to provide!), we could do this:

from inspect import signature, Signature, Parameter
from operator import itemgetter
from typing import Callable

f = "hello {name} how are you {verb}?".format

def templated_string_func(template: str) -> Callable:
    """A function making templated strings. Like template.format, but with a signature"""
    f = partial(str.format, template)
    names = filter(None, map(itemgetter(1), string.Formatter().parse(template)))
    params = [Parameter(name=name, kind=Parameter.KEYWORD_ONLY) for name in names]
    f.__signature__ = Signature(params)

    return f

f = templated_string_func("hello {name} how are you {verb}?")
assert f(name='Christian', verb='doing') == 'hello Christian how are you doing?'
assert str(signature(f)) == '(*, name, verb)'

But would if we want to make dict factories? Something having this behavior:

g = templated_dict_func(template={'hello': '$name', 'how are you': {'$verb'}})
assert g(name='Christian', verb='doing') == {'hello': '$name', 'how are you': {'$verb'}

What about other types of objects?

It seems like something that would have a solid design pattern...

Aucun commentaire:

Enregistrer un commentaire