[Tutor] To FORMAT or not to

Steven D'Aprano steve at pearwood.info
Sun Jan 3 21:03:22 EST 2016


On Sun, Jan 03, 2016 at 02:04:22PM +0100, Chris Warrick wrote:

> Here are a couple of reasons:
> * String formatting works everywhere, but this syntax is specific to
> print() — if you use something else, you might end up producing faulty
> code

That argument doesn't make sense to me. I think you mean semantics, 
not syntax, as print uses the same syntax as all Python functions. But 
the same might be said about EVERY function and method.

I might say, "Don't use format, because the semantics is specific to 
format -- if you use something else, you might end up producting faulty 
code". Well duh, of course it would, but if I used something else, I 
wouldn't give it arguments that format requires. The same applies to 
print, and literally every single other function and method.


> * The corrected string formatting usage is more readable than the
> original print()

That's a matter of opinion, and not one that I share.


> * String concatenation with + requires that all arguments are strings,
> which is even less readable

Again, that's a matter of opinion, and it's not a very credible opinion. 
You're arguing that using a complex mini-language with mysterious pairs 
of braces plus a method call:

    print("blah blah blah {}.".format(s))

is more readable than a simple concatenation:

    print("blah blah blah", s + ".")


I think not.


> * With string formatting, you can apply special formatting to your
> inputs (eg. set width, number precision…), which is hard or impossible
> with print()

*shrug*

Nobody says that format isn't capable of more advanced formatting 
control than print. That's format's purpose, after all, just as print's 
purpose is to print. But for the example given, when the formatting 
needed is trivial and well within the capabilities of print, there's no 
need to involve format.

The SpaceX "Falcon" rocket will take you to space, and a skate-board 
will take you around the block. If you strap a Falcon rocket to a 
skate-board, and lay it on the ground, you can also use a Falcon to go 
around the block. But why would you bother?

> * Using print() with commas adds spaces between all entries, which
> might look bad (and it does in this example); 

Say what? Adding spaces between the entries is exactly what is needed 
here, and it looks fine:

py> island = "Mothering Sunday Island"
py> new = "cuddled a tree-climbing octopus"
py> print("You've visited", island, '&', new + ".")
You've visited Mothering Sunday Island & cuddled a tree-climbing octopus.


> the only way to prevent
> that is by setting `sep=`, but then you need to remember about a space
> after "visited" and around the ampersand…

What? This argument makes no sense. There's no need to set sep='', the 
example works fine with the default single space separator.



> * Easy to localize (translate into different languages), which is
> generally impossible with any of the other options (some languages
> might rearrange the sentence!)

A translation engine might use format internally for *part* of the job, 
but the usual way to handle localisations is to call a function 
(conventionally named underscore) to do the work. That *might* involve 
using a template designed for format:

_("You've visited {} & {}.", island, new)

but could just as likely involve % or $ placeholders. That will allow 
both the template and the terms to be localised. In any case, it is not 
likely to involve a direct call to format for exactly the same reason 
that it isn't likely to involve a direct use of print's simple format 
control: it is too simple.

Not only can word-order change, but a single word that gets injected 
into one place of the template in Language A might end up being two 
terms that are injected into two widely-separated places in Language B:

# Language A
"blah blah blah blah {0} blah {1} blah blah", a, b

# Language B
"blah blah {1} blah blah blah {0} blah blah {2} blah blah", a, b, c

(and, by the way, the punctuation needs to be localised too). The 
localisation engine can deal with that complexity. Trying to manage 
translations yourself using just format cannot (or at least not easily).

But fundamentally, the problem with this argument is YAGNI ("You Aren't 
Going To Need It"). Don't over-engineer a simple script just in case 
someday you will need to localize it for arbitrary languages. You won't. 
And if you do, *that* is the time to rewrite the print call to include a 
localisation step, not now.



-- 
Steve


More information about the Tutor mailing list