[Python-ideas] One way to do format and print

Stephen J. Turnbull stephen at xemacs.org
Tue Sep 8 05:01:44 CEST 2015

Random832 writes:

 > But anyway, my ideal version of it would have a .format method, but
 > using identical format strings.

"Identical" is impossible, even you immediately admit that an
extension is necessary:

 > My real question was what the benefit of the {}-format for format
 > strings is, over an extended %-format.

One issue is that the "%(name)s" form proves to be difficult for
end-users and translators to get right.  Eg, it's a FAQ for Mailman,
which uses such format strings for interpolatable footers, including
personalized user unsubscribe links and the like.  This is just a
fact.  I don't have any similar evidence that "{}" is better.

Introspecting, I find have the whole spec enclosed in parentheses far
more readable than the very finicky %-specs.  It feels more like a
replacement field to me.  I also find the braces to be far more
readable parenthesization than (round) parentheses (TeX influence
there, maybe?)  In particular, these two attributes of "{}" are why
I use .format by preference even in simple cases where % is both
sufficient and clearly more compact.  Obviously that's a personal
preference but I doubt I'm the only one who feels that way.

%-formatting provides no way to indicate which positional parameter
goes with which format spec.  It was hoped that such a facility might
be useful in I18N, where the syntax of translated string often must be
rather different from English syntax.  That has turned out not to be
the case, but that is the way the C world was going at the time.  In
recent C (well, C89 or C99 ;-) there is a way to do this, but that
would require extending the Python %-spec syntax.

{}-formatting allows one level of recursion.  That is

    "|{result:{width}d}|".format(result=42, width=10)

produces "|        42|".  In %-formatting, a recursive syntax would be
rather finicky, and an alternative syntax for formatting the format
spec would be shocking to people used to %-formatting, I guess.

{}-formatting actually admits an arbitrary string after the ":", to be
interpreted by the object's __format__ method, rather than by format.
The {arg : sign width.prec type} format is respected by the builtin
types, but a type like datetime can (and does!) support the full
strftime() syntax, eg,

    "It is now {0:%H:%M:%S} on {0:%Y/%m/%d}.".format(datetime.now())

produced 'It is now 11:58:53 on 2015/09/08.' for me just now.  I
don't see how equivalent flexibility could be provided with %-spec
syntax without twisting it completely out of shape.

These last three, besides presenting (more or less minor) technical
difficulties for a %-spec extension, run into Guido's allergy to
subtle context-dependent differences in syntax, as we've seen in the
discussion of whether expression syntax in f-strings should be
restricted as compared to "full" expression syntax.  That is, the more
natural the extension of %-spec syntax we used, the more confusing it
would be to users, especially new users reading old code (and
wondering why it does things the hard way).  OTOH, if it's not a
"natural" extension, you lose many of the benefits of an extension in
the first place.

More information about the Python-ideas mailing list