Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a callable equivalent to f-string syntax?

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'
like image 835
David Eyk Avatar asked Oct 10 '17 19:10

David Eyk


People also ask

Can you call a function in an F string?

Python f-strings enables us to call functions within it.

What is f {} in Python?

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.

Are F strings still used in Python?

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.


1 Answers

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.

like image 127
Sergey Vasilyev Avatar answered Oct 23 '22 05:10

Sergey Vasilyev