On 6/21/2011 7:33 AM, Tim Chase wrote:
On 06/20/2011 09:17 PM, Terry Reedy wrote:
On 6/20/2011 8:46 PM, Tim Chase wrote:
On 06/20/2011 05:19 PM, Ben Finney wrote:
“This method of string formatting is the new standard in
Python 3.0, and should be preferred to the % formatting
described in String Formatting Operations in new code.”

<URL:http://docs.python.org/library/stdtypes.html#str.format>

Is there a good link to a thread-archive on when/why/how .format(...)
became "preferred to the % formatting"?

That is a controversial statement.

I'm not sure whether you're "controversial" refers to

- the documentation at that link,
- Ben's quote of the documentation at that link,
- my quotation of Ben's quote of the documentation,
- or my request for a "thread-archive on the when/why/how"

I _suspect_ you mean the first one :)

I meant the preceding statement (derived from the linked source, but that is not important) that .format is preferred to %. Guido prefers it. I prefer it. At least a couple of developers vocally do not prefer it and might prefer that the statement was not there. Guido recognizes that deprecation of % formatting would at least require a conversion function that does not now exist.

I see that the linked doc says 'in new code'. That makes the statement less (but only less) controversial.


I haven't seen any great wins of the new formatting over
the classic style.

It does not abuse the '%' operator,

Weighed against the inertia of existing code/documentation/tutorials, I
consider this a toss-up. If .format() had been the preferred way since
day#1, I'd grouse about adding/overloading '%', but going the other
direction, there's such a large corpus of stuff using '%', the addition
of .format() feels a bit schizophrenic.

it does not make a special case of tuples (a source of bugs),

Having been stung occasionaly by this, I can see the benefit here over
writing the less-blatant

"whatever %s" % (tupleish,)

and it is more flexible, especially
indicating objects to be printed. Here is a simple example from my code
that would be a bit more difficult with %.

multi_warn = '''\
Warning: testing multiple {0}s against an iterator will only test
the first {0} unless the iterator is reiterable; most are not.'''.format
...
print(multiwarn('function'))
...
print(multiwarn('iterator'))

Does the gotcha of a non-restarting iterator

Huh? What iterator?

> trump pulling each field  you want and passing it explicitly?

Huh? I explicitly pass the strings to be printed.

In pre-.format(), I'd just use dictionary formatting:

"we have %(food)s & eggs and %(food)s, bacon & eggs" % {
"food": "spam", # or my_iterator.next()?
}

A better parallel to my example would be

menu = "We have %(meat)s & eggs or %(meat)s and potatoes."
print(menu % {'meat':'spam'})
print(menu % {'meat':'ham'})

The exact duplicate of that with .format is

menu = "We have {meat} & eggs or {meat} and potatoes.".format
print(menu(meat = 'spam'))
print(menu(meat = 'ham'))

One knock against '.format' is that it is 6 chars more that '%'. But for repeat usage, it is only needed once. And look: '%(meat)s' is 2 more chars than '{meat}' and, to me, {} is easier to type than (). Then " % {'meat':"spam"}" is 3 more chars than "(meat = 'ham')" and definitely harder to type. While I prefer '}' to ')', I prefer '))' to the mixed '})'. The % way is at least 'a bit more difficult' even compared to the longer and harder .format with named fields.

menu = "We have {0} & eggs or {0} and potatoes.".format
print(menu('spam'))
print(menu('ham'))

it a little easier yet, though perhaps less clear, especially if there were multiple substitutions.

The other new feature I saw was the use of __format__() which may have
good use-cases, but I don't yet have a good example of when I'd want
per-stringification formatting compared to just doing my desired
formatting in __str__() instead.

__str__ always returns the same string for an instance in a given state.
Similarly, __float__ and __int__ will return the same float or int version of an unchanged instance. __format__(spec) can directly adjust the result according to spec without the restriction of going through an intermediary str, int, or float.

Suppose one had a Money class with currency and decimal amount fields. .__str__ can add a currency symbol (before or after as appropriate) but has to use a standard format for the amount field. .__float__ can be post-processed according to a %...f spec, but cannot include a currency symbol. Money.__format__(self,spec) can format the amount at it wishes, including its rounding rules, *and* add a currency symbol.

Or suppose one has a multi-precision float. %80.40f will require an mpf instance to appoximate itself as a float, possibly with error. mpg.__format__ should be able to do better.

(Sadly, this new ability to more accurately represent objects is not yet used for ints and is broken for fractions.Fraction. I will probably post issues on the tracker.)

--
Terry Jan Reedy


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to