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 👿 we have now third way to do the same thing. Yay!

Credit goes to xkcd

…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’.

0

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.