Method for interpolate "normal" string like an f-string

f-strings are very handy and readable. But they are evaluated where they are coded.

robot = "positronic"
statement = f"I want a {robot} brain"

If you want a reusable template, you have to use format or the % syntax with a “normal” string:

robot = "positronic"
tpl = "I want a {robot} brain"
statement = tpl.format(robot=robot)

If you have a lot of interpolations to do, this will turn to be quite tedious very quickly. This is one of the reasons f-strings became so popular.

I propose to add yet another method to str, to interpolate the string like it is an f-string:

robot = "positronic"
tpl = "I want a {robot} brain"
statement = tpl.interpolate()

In this way you can have a reusable template easy to use as an f-string.

If PEP 750 will be implemented, obviously this proposal will became superseded.

Side note: interpolate seems to me too long, but I can’t think a better name now.

You can use tpl.format(**locals()).

4 Likes

This is a good way to do this “right now” I didn’t think about and I’ll definitively use it. Notice anyway this does not work as f-strings, since they can accept also globals and expressions.

If it were plausible to do that, we wouldn’t have needed f-strings in the first place, and the method would have been sufficient.

You can do eval('f' + repr(tpl)). Note that the usage of eval correctly indicates that this a dangerous operation that opens you up to security issues if you do it with untrusted data.

4 Likes

Or tpl.format_map(locals()).

And another:

robot = "positronic"
tpl = lambda: f"I want a {robot} brain"
statement = tpl()
4 Likes

I think this is the best solution.

FWIW, when I need to do something like this, I either do:

fmt = "I want a {} brain".format
fmt("positronic")

Or:

fmt = "I want a {robot} brain".format
fmt(robot="positronic")

The lambda trick will work if I’m doing something like:

timestamp = lambda: f"Elapsed time {time.time() - tic}"
tic = time.time()

# Do something
timestamp()
# Do something else
timestamp()

But I think I’m not polling the value of a changing variable or expression as often as I want to format a bunch of one-off values.

1 Like