Search code examples
pythontemplatesf-string

Is there a way to unpack a dictionary into an f-string **template**?


With .format we can unpack a dictionary into a string template. That's the only thing I haven't found how to do with f-strings. Is there a way to do it?

E.g. how to do this with f-strings?

template = "my values: {number} {item}"
values = dict(number=1, item='box')

print(template.format(**values))

Edit:

I thought you can have f-string templates for undefined values with something like this, but it doesn't work either:

template2 = "my values: {(number := None)} {(item := None)}" # values are immutable after defining
values = dict(number=1, item='box')

# how to unpack `values` into `template2`, is it possible?

I'm aware of the longer ways to do it, what I'm looking for is only whether it's possible to use unpacking. Cheers!!


Solution

  • What's wrong with these:

    values = dict(number=1, item='box')
    print(f"{values=}")
    print(f"values= {values['number']} {values['item']}{values.get('missing')}")
    

    which gets you:

    values={'number': 1, 'item': 'box'}
    values= 1 box None
    

    Or do you want to declare your f-string before you've set up the dict and then plug in the dict? Sorry, no can do, f-strings get evaluated right away, they are not really pre-defined templates.

    Pre-defined templates hack

    I've worked a lot with templates, usually the %(foo)s kind or else Jinja2 templates and have missed the capability to pass templates around, when using f-strings.

    This below is a hack, but it does allow doing that, after a fashion. Thought of doing that a while back, never tried it though.

    def template_1(**values):
        number = values["number"]
        item = values["item"]
        missing = values.get("missing")    
        return f"values1= {number} {item} {missing}"
    
    def template_2(**values):
        return f"values2= {values['number']} {values['item']} {values.get('missing')}"    
    
    print(template_1(**values))
    
    def do_it(t, **kwargs):
        return t(**kwargs)
    
    print(do_it(template_2,missing=3, **values))
    
    

    Output

    values1= 1 box None
    values2= 1 box 3