F-Strings

You can learn more about f-strings from this page: realpython.com on f-strings.

The Realpython page about f-strings has only one objection to the .format() method, and that's because they didn't notice that the .format() method works just fine on multi-line, triple-quoted strings. So, the "disadvantage" they describe is an illusion.

Nevertheless, you're still welcome to use f-strings. Now that I know something about them, I can see the advantage in some cases, and I may well start using them in new code.

The Realpython page also describes a speed advantage to f-strings, but that's also an illusion. Here's why. The following code creates and assigns three variables and then formats a nice sentence about them, using keyword-argument style. The timer then runs that code 1000 times and collects the total time. It does that five times.

code = """
num = 1
denom = 4
quo = 0.25
'{num} over {denom} is {quo}.'.format(num=num, denom=denom, quo=quo)"""
t = timeit.Timer(code)
t.repeat(number=1000, repeat=5)

Here are the five results of running that code:

t.repeat(number=1000, repeat=5)
[0.005410064943134785, 
 0.0051551200449466705, 
 0.005029347958043218, 
 0.004987671039998531, 
 0.0048216048162430525]

Looking over these, you'll see that, the worst time for doing 1000 calls to the .format method is 5.4 milliseconds, which means that each call takes 5.4 microseconds. This is a negligible amount of time unless you are doing a gargantuan number of calls to .format().

For context, our network overhead from browser to server is often dozens of milliseconds. So saving a few microseconds will be unnoticeable.

Looking back at the Realpython page, we see that they showed a decrease from about 4 milliseconds to about 2 milliseconds, which is a huge 50 percent speedup. But you'll also see that they ran the formatting code 10,000 times. So the real difference is from less than 1 microsecond to half that. Again, the user will not notice that.

Dictionaries

I wanted to highlight the following feature, about which the Realpython people say

You can also use ** to do this neat trick with dictionaries:

Here's their example:

person = {'name': 'Eric', 'age': 74}
"Hello, {name}. You are {age}.".format(**person)

What the magic ** syntax does is unpack a dictionary into a series of key-value pairs, which you can turn around and hand to the .format() method, which wants a bunch of keyword arguments. If the placeholders have the same names as the keys to the dictionary, you have this magically compact syntax.

Why would this be so notable? Because our database queries will often be dictionaries. So you can do:

curs = dbi.dict_cursor(conn)
curs.execute('select name, birthdate from person')
for row in curs.fetchall():
    print('{name} was born on {birthdate}'.format(**row)

This neat trick might justify sticking to the .format() method all by itself. But I'm reluctant to throw too much magic at you.

If you want to learn more about packing and unpacking in Python, you can check that link.