Everybody loves Python 3.6's new f-strings:
In [33]: foo = {'blah': 'bang'}
In [34]: bar = 'blah'
In [35]: f'{foo[bar]}'
Out[35]: 'bang'
However, while functionally very similar, they don't have the exact same semantics as str.format()
:
In [36]: '{foo[bar]}'.format(**locals())
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-36-b7ef5aead76c> in <module>()
----> 1 '{foo[bar]}'.format(**locals())
KeyError: 'bar'
In particular, str.format()
handles getitem syntax very differently:
In [39]: '{foo[blah]}'.format(**locals())
Out[39]: 'bang'
Given the ability to handle full-blown python expression syntax, f-strings are wonderful and I love them. But they have one hitch: they're evaluated immediately, whereas with str.format()
I can save the string with its formatting as a template, and format it multiple times in different contexts.
So, is there an equivalent way to save a string as a template, and evaluate it, using f-string semantics, at a later date? Other than defining a function? Is there an equivalent to str.format()
for f-strings?
Update:
So, hypothetical interface here as an example:
In [40]: mystr = '{foo[bar]}'
In [41]: make_mine_fstring(mystr, foo=foo, bar=bar)
Out[41]: 'bang'
Python f-strings enables us to call functions within it.
The f-string was introduced(PEP 498). In short, it is a way to format your string that is more readable and fast. Example: The f or F in front of strings tells Python to look at the values inside {} and substitute them with the values of the variables if exist.
But in Python 3.6 and later, you can use f-Strings instead. f-Strings, also called formatted string literals, have a more succinct syntax and can be super helpful in string formatting. In this tutorial, you'll learn about f-strings in Python, and a few different ways you can use them to format strings.
Brief answer: NO.
You can read PEP-498 regarding these f-strings. It clearly defines their purpose, and the concept: these strings are evaluated in-place. The result is a usual str
with formatted content. You cannot store f-strings as a template, as there is no special object for f-strings.
Your specific example is also mentioned in PEP-498's "Differences between f-string and str.format expressions" section.
So, whatever you do, you either use the inline in-place f-strings, or the old s.format()
syntax, with different behaviour.
If you want to read an f-string from a file and evaluate it according to the syntax of f-strings, you could use eval:
foo = {'blah': 'bang', 'bar': 'sorry'}
bar = 'blah'
tpl = '{foo[bar]}'
print(tpl)
print(tpl.format(**locals())) # sorry
print(eval(f'f{tpl!r}')) # bang
Note how we use the f-string first, but convert the tpl
into its own repr for immediate eval. Typically, for simple types, eval(repr(val))
should return val
. But instead of just putting repr(tpl)
(or {tpl!r}
), we convert the repr of the regular string into the f-string, and evaluate it instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With