Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8007 > unrolled thread

Re: What is this syntax ?

Started byClaudiu Popa <cpopa@bitdefender.com>
First post2011-06-20 10:18 +0300
Last post2011-06-21 18:02 -0500
Articles 7 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Re: What is this syntax ? Claudiu Popa <cpopa@bitdefender.com> - 2011-06-20 10:18 +0300
    Re: What is this syntax ? Ben Finney <ben+python@benfinney.id.au> - 2011-06-21 08:19 +1000
      Re: new string-formatting preferred? (was "What is this syntax ?") Tim Chase <python.list@tim.thechases.com> - 2011-06-20 19:46 -0500
      Re: new string-formatting preferred? (was "What is this syntax ?") Terry Reedy <tjreedy@udel.edu> - 2011-06-20 22:17 -0400
      Re: new string-formatting preferred? (was "What is this syntax ?") Tim Chase <python.list@tim.thechases.com> - 2011-06-21 06:33 -0500
      Re: new string-formatting preferred? (was "What is this syntax ?") Terry Reedy <tjreedy@udel.edu> - 2011-06-21 18:19 -0400
      Re: new string-formatting preferred? (was "What is this syntax ?") Tim Chase <python.list@tim.thechases.com> - 2011-06-21 18:02 -0500

#8007 — Re: What is this syntax ?

FromClaudiu Popa <cpopa@bitdefender.com>
Date2011-06-20 10:18 +0300
SubjectRe: What is this syntax ?
Message-ID<mailman.178.1308554725.1164.python-list@python.org>
Hello,

Isn't this similar to php interpolation? And quite readable imo.

>>> import string
>>> template = string.Template("$scheme://$host:$port/$route#$fragment")
>>> template.substitute(scheme="http", host="google.com", port="80", route="", fragment="")
'http://google.com:80/#'
>>>


Roy Smith wrote:

> There's something nice about building up strings in-line, as
> opposed to having to look somewhere to see what's being interpolated.
> To give a more complex example, consider:
> 
> print "$scheme://$host:$port/$route#$fragment"
> 
> That certainly seems easier to me to read than:
> 
> print "%s://%s:%s/%s#%s" % (scheme,
>                             port,
>                             host,
>                             route,
>                             fragment)

  

[toc] | [next] | [standalone]


#8033

FromBen Finney <ben+python@benfinney.id.au>
Date2011-06-21 08:19 +1000
Message-ID<87pqm8qh7m.fsf@benfinney.id.au>
In reply to#8007
Claudiu Popa <cpopa@bitdefender.com> writes:

> Hello,

(Please don't top-post. Instead, interleave your responses below each
quoted part you're responding to, as in this message. See also
<https://secure.wikimedia.org/wikipedia/en/wiki/Posting_style#Interleaved_style>.)

> Isn't this similar to php interpolation? And quite readable imo.
>
> >>> import string
> >>> template = string.Template("$scheme://$host:$port/$route#$fragment")
> >>> template.substitute(scheme="http", host="google.com", port="80", route="", fragment="")
> 'http://google.com:80/#'
> >>>

This style is so useful that a very similar system was proposed, and
accepted, in PEP 3101 as a method of the built-in types. It makes most
uses of the ‘string.Template’ class obsolete.

The text types (‘str’, ‘unicode’) now have a very similar capability as
part of the type. Works in Python 2.6 or later, and Python 3 or later.

    >>> template = "{scheme}://{host}:{port}/{route}#{fragment}"
    >>> template.format(scheme="http", host="google.com", port="80", route="", fragment="")
    'http://google.com:80/#'

“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>

-- 
 \                “Room service? Send up a larger room.” —Groucho Marx |
  `\                                                                   |
_o__)                                                                  |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#8045 — Re: new string-formatting preferred? (was "What is this syntax ?")

FromTim Chase <python.list@tim.thechases.com>
Date2011-06-20 19:46 -0500
SubjectRe: new string-formatting preferred? (was "What is this syntax ?")
Message-ID<mailman.204.1308617185.1164.python-list@python.org>
In reply to#8033
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"?  I haven't 
seen any great wins of the new formatting over the classic style. 
  Is there some great feature of new-style formatting that I've 
missed out on that obviates bajillions of lines of 2.x code?

-tkc

[toc] | [prev] | [next] | [standalone]


#8056 — Re: new string-formatting preferred? (was "What is this syntax ?")

FromTerry Reedy <tjreedy@udel.edu>
Date2011-06-20 22:17 -0400
SubjectRe: new string-formatting preferred? (was "What is this syntax ?")
Message-ID<mailman.209.1308622639.1164.python-list@python.org>
In reply to#8033
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 haven't seen any great wins of
> the new formatting over the classic style. Is there some great feature
> of new-style formatting that I've missed out on that obviates bajillions
> of lines of 2.x code?

It does not abuse the '%' operator, it does not make a special case of 
tuples (a source of bugs), 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'))

Here is a more complex example:

class chunk():
	def __init__(self, a, b):
		self.a,self.b = a,b
c=chunk(1, (3,'hi'))
print('{0.__class__.__name__} object has attributes int a <{0.a}> and 
tuple b with members <{0.b[0]}> and <{0.b[1]}>'.format(c))
 >>>
chunk object has attributes int a <1> and tuple b with members <3> and <hi>

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#8085 — Re: new string-formatting preferred? (was "What is this syntax ?")

FromTim Chase <python.list@tim.thechases.com>
Date2011-06-21 06:33 -0500
SubjectRe: new string-formatting preferred? (was "What is this syntax ?")
Message-ID<mailman.223.1308656004.1164.python-list@python.org>
In reply to#8033
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 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 trump pulling each 
field you want and passing it explicitly?  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()?
     }


> class chunk():
> 	def __init__(self, a, b):
> 		self.a,self.b = a,b
> c=chunk(1, (3,'hi'))
> print('{0.__class__.__name__} object has attributes int a<{0.a}>
> and tuple b with members<{0.b[0]}>  and<{0.b[1]}>'.format(c))

This was one of the new features I saw, and I'm not sure how I 
feel about my strings knowing about my object structure.  It 
feels a bit like a violation of the old "separation of content 
and presentation".  Letting string-formatting reach deeply into 
objects makes it harder to swap out different object 
implementations purely by analyzing the code.  It also can put 
onus on translators to know about your object model if your 
format-strings come from an i18n source.  I also see possible 
mechanisms for malicious injection if the format-string comes 
from an untrusted source (unlikely, but I've seen enough bad code 
in production to make it at least imaginable).

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.

So even with your examples of differences, I don't get an 
overwhelming feeling of "wow, that *is* a much better way!" like 
I did with some of the other new features such as "with" or 
changing "print" to a function.

Anyways, as you mention, I suspect blessing .format() as 
"preferred" in the documentation was a bit contentious...with 
enough code still running in 2.4 and 2.5 environments, it will be 
a long time until I even have to think about it.  I just wanted 
to watch a replay of the decision-makers bashing it out :)

-tkc


[toc] | [prev] | [next] | [standalone]


#8138 — Re: new string-formatting preferred? (was "What is this syntax ?")

FromTerry Reedy <tjreedy@udel.edu>
Date2011-06-21 18:19 -0400
SubjectRe: new string-formatting preferred? (was "What is this syntax ?")
Message-ID<mailman.246.1308694779.1164.python-list@python.org>
In reply to#8033
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

[toc] | [prev] | [next] | [standalone]


#8141 — Re: new string-formatting preferred? (was "What is this syntax ?")

FromTim Chase <python.list@tim.thechases.com>
Date2011-06-21 18:02 -0500
SubjectRe: new string-formatting preferred? (was "What is this syntax ?")
Message-ID<mailman.249.1308697338.1164.python-list@python.org>
In reply to#8033
On 06/21/2011 05:19 PM, Terry Reedy wrote:
> On 6/21/2011 7:33 AM, Tim Chase wrote:
>>>>> <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,
>
> I meant the preceding statement (derived from the linked source, but
> that is not important) that .format is preferred to %.

I guess then with all the contention, having such a vocal 
preference in the docs (even if tempered by "in new code") seems 
to unnecessarily polarize when I find myself very "meh" in either 
direction.

>>> 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?

Your string-body text warns about behavior regarding iterators. 
I was thrown by your warning.

>> The other new feature I saw was the use of __format__()
>
> 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.

A Money class was one of the first things I thought of, but 
figured that would be better relegated to an i18n wrapper if you 
wanted it.  Such a wrapper would handle currency-symbol choice & 
positioning positioning (before vs. after; relation to the +/-; 
optional characters for thousands-separators and decimal 
separators; and partitioning at thousands-or-other-multiples, etc).

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

This case makes a better argument, showing me some new value 
added by __format__().

-tkc


[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web