f-string anomaly
Terry Reedy
tjreedy at udel.edu
Sun May 13 22:08:32 EDT 2018
On 5/13/2018 3:22 PM, Ken Kundert wrote:
Please do not double post.
> I am seeing an unexpected difference between the behavior of the string
> format method and f-strings.
Read
https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals
carefully.
> Here is an example:
>
> import sys, os
> from inform import error, os_error
>
> class mydict(dict):
> def __format__(self, template):
> print('Template:', template)
> return ', '.join(template.format(v, k=k, v=v) for k, v in
> self.items())
>
>
> d = mydict(bob='239-8402', ted='371-8567', carol='891-5810',
> alice='552-2219')
>
> print('Using format():')
> print('Email: {0:{{k}}: {{v}}}'.format(d))
> print()
> print('Using f-string:')
> print(f'Email: {d:{{k}} {{v}}}')
> print()
> print('Using f-string:')
> print(f'Email: {d:{{k}} {{v}}}', k=6, v=9)
>
>
> It generates the following response:
>
> Using format():
> Template: {k}: {v}
> Email: bob: 239-8402, ted: 371-8567, carol: 891-5810, alice: 552-2219
>
> Using f-string:
> Traceback (most recent call last):
> File "tryit", line 18, in <module>
> print(f'Email: {d:{{k}} {{v}}}')
> NameError: name 'k' is not defined
This is what I expected.
> Essentially I am using a format string as the template that indicates
> how to format each member of a dictionary, {{k}} should interpolate the
> key and {{v}} interpolates the value. This format string is embedded
> inside another format string, so the braces are doubled up so that they
> will be ignored by the outer format string.
"The parts of the string outside curly braces are treated literally,
except that any doubled curly braces '{{' or '}}' are replaced with the
corresponding single curly brace. " note 'outside'
> This idea seems to work okay when using the format() method. You can see
> I added a print statement inside __format__ that shows that the method
> is being called.
>
> However, trying the same idea with f-strings results in a NameError. It
> appears that the escaping does not work when used within the template.
> It appears the error occurs before __format__ is called (there is no
> output from the print function).
>
> Does anybody know why the format() method would work in this case but
> the f-string would not?
All names in the expression are resolved in the local namespace of the f
string. There are other differences. Nesting can only be one level deep.
> Is this a bug in f-strings?
Not to me.
--
Terry Jan Reedy
More information about the Python-list
mailing list