Post

Python 3.6 new features - formatted string literals

On 23. December 2016 new minor version of Python was released - 3.6. It brings few enhancements and syntax features. In my opinion the most notable one is introduction of formatted string literals.

word = 'world'
print(f'Hello, {word}!')  # prints 'Hello, world

I always envied Ruby's string interpolation because it is much cleaner and doesn't require programmer to read end of expression just to understand what is substituted where.

String interpolation was always a pain in Python. Not to mention there is more than one way to do it...

some_string = "I'm %s" % ('interpolated', )
other_string = "I'm {}".format('interpolated')

Clear violation of Zen of Python that states:

There should be one-- and preferably only one --obvious way to do it.

In order to violate it even more :evil: we have now third way to do the same thing. Yay!

[caption id="attachment_67" align="aligncenter" width="500"] Credit goes to xkcd[/caption]

...but its actually better than previous ones. Syntax of first one is quite concise, but can cause some troubles for python newcomers:

some_string = "I'm %s" % ('interpolated', )
other_string = "I'm %s" % 'interpolated'  # The same thing! 
another_string = '%s %s' % ("I'm", "interpolated")
yet_another_string = '%s %s' % "I'm", "interpolated"  # Not an option! Raises TypeError

There is a shortcut that allows to omit giving tuple as argument for string interpolation, but it won't work with more than one argument. Nevertheless - this syntax makes it easy to format arguments just like old good sprintf does.

'%.2f ' % 5  #  Prints any numeric value as floating point
'%.2f ' % Decimal('5.1254')
'%.2f ' % 5.144

The same thing can be accomplished using "old-new" .format:

'{:.2f}'.format(5)
'{:.2f}'.format(Decimal('1.1254'))
'{:.2f}'.format(5.144)

Way more verbose than previous syntax. Differences between string interpolation are presented on pyformat.info - awesome work done by Ulrich Petri and Horst Gutmann.

Getting back to new syntax - it naturally has all features of "old-new" string interpolation with .format function, but removes need to actually call this method.

value = Decimal('1.2354')
f'{value:.2f}'

This becomes especially helpful when formatting long strings (try to fit in standard PEP8's 80 characters per line without awkward line breaks) or in classes:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Point<{self.x}, {self.y}>'

point = Point(3, 5)
print(point)  # Point<3, 5>

This was merely a sneak peek of string formatting in Python, but it presented essential aspects of new so-called 'f-strings'.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.