f-string anomaly

Ken Kundert theNurd at nurdletech.com
Sun May 13 19:25:35 EDT 2018


I am seeing an unexpected difference between the behavior of the string
format method and f-strings in Python3.6.

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

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.

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?

Is this a but in f-strings?

-Ken



More information about the Python-list mailing list