With Python being such an elegant language generally, it’s a surprise to come across features that don’t feel as well-designed as they could have been. Formatted printing is one such feature.

Consider how this works in Python 3. Strings have a format method, to which we must pass the values to be formatted. The string itself defines placeholders for those values and provides formatting directives that control the final appearance of the values. The format method returns a string, which is typically then passed to the print function. Here’s an example:

print("{:d} values, mean = {:.3f}".format(num_values, mean))

For some reason, invoking a method on a literal value always looks a little odd to me. Of course, this can be avoided by introducing a variable to represent the format string, at the risk of making the code more complicated:

template = "{:d} values, mean = {:.3f}"
print(template.format(num_values, mean))

Now let’s imagine that Python has a printf function, analogous to that in C. The format string is passed in as the first argument and the values to be formatted are passed as the remaining arguments. Our code example now becomes

printf("{:d} values, mean = {:.3f}", num_values, mean)

Simpler and cleaner, in my view.

Sadly, Python does not have such a printf function, but it isn’t difficult to provide your own:

def printf(template, *args, **kwargs):
    result = template.format(*args)
    print(result, **kwargs)

The *args parameter collects the arguments to be formatted. The **kwargs parameter allows printf to support the various keyword arguments that can be used with the built-in print function.


comments powered by Disqus