New Python 3.0 string formatting - really necessary?

C

Carl Banks

Marc,
Why move away from a concise and widely accepted way of sting
formatting, just to supposedly make it a little easier for n00bs?

You were the one that brought it up, chief. I doubt anyone is arguing
that this new formating was added just to make things easier for
newbies, we're just saying that your assertion that printf-style is
much easier for newbies is wrong.

If you care to, go read the rationale for this change PEP 3101. You'd
see the new formating was added to address limitations of the printf-
style. (Hint: the limitations aren't that %s, %d, and %f are hard to
remember.)

*It may be time to start hacking my own personal version of the Python
interpreter. hmm... Keep you ears to the ground...

My friend, if you can't even cope with a new system of string
formating, do you really expect to be able to maintain your own hacked-
up fork of a highly wrought out programming language?


Carl Banks
 
C

Carl Banks

It's not going to be removed for many years - if ever. The % string
formatting system is not deprecated in 3.0. For that very reason it must
stay until 3.2. We don't have plans to deprecate it in 3.1 so it will
stay at least until Python 3.3 which is to be released about 2014.

I wish they would have at least deprecated or got rid of the %
operator, because that's ugly. There's no reason they couldn't have
added another method for printf-style formating, e.g.:

"The answer is %s.".sprintf("yes")


Carl Banks
 
S

Steven D'Aprano

Ah, but for internationalization, you can change the format string to
take args in a different order if, for example, French messages want
modifiers on one side and English on the other. The code can stay the
same, while only the text used to do the formatting must change.

I can't see how this is any different between what we have now. Here's an
example using keyword arguments:

# untested
"{modifier} {noun}".format(modifier="dead", noun="parrot")
"{noun} {modifier}".format(modifier="mort", noun="perroquet")

compared to:

"%(modifier)s %(noun)s" % dict(modifier="dead", noun="parrot")
"%(noun)s %(modifier)s" % dict(modifier="mort", noun="perroquet")

Whether using % or format(), I don't see the need to change the code,
only the strings.

Using positional arguments is not really that different:

"{0} {1}".format("dead", "parrot")
"{0} {1}".format("perroquet", "mort")

versus:

"%s %s" % ("dead", "parrot")
"%s %s" % ("perroquet", "mort")

In this case, the template on the left remains the same, you just have to
reorder the string arguments on the right. Clearly less satisfactory than
the solution using keyword substitution, but whatever solution you pick,
I don't see any advantage to format() over % formatting. Can you show an
example?
 
R

r

Thanks Steven,
We need a real Pepsi challenge here to show the insignificance of this
change. I am not against change. But when we lose something as -
compact- as %formating i'm going to want to see a damn good reason for
it! Especially when this breaks code, and the "French Connection" is
not good enough reason for me :)

Christian said this was not going to be depreciated until 3.2, but
that still puts the accepted way on the chopping block.
 
S

Steven D'Aprano

Why move away from a concise and widely accepted way of sting
formatting, just to supposedly make it a little easier for n00bs? (which
i disagree this is easier) In turn, creating more syntactical clutter.
(%s %f %d) is all you need to remember. If people can't understand that,
i fear for the future of Humans as a species!

Reading your wibbling, so do I. Take ten deep breaths and calm down.

Firstly, the introduction of format() is not to "make it a little easier
for n00bs" as you claim, but to allow more powerful, flexible string
formatting.

Secondly, to use % formatting to full effectiveness you need to know MUCH
more than (%s %f %d). You need to know:

Formatting codes: %s %r %d %f %g %G %c %i %u %o %x %X %e %E %%
(have I missed any?)
Keyword formatting: %(name)s
Flags: - + 0
Field width and precision, including the special case of "*"

and how they fit together:

%[(name)][flags][width][.precision][unused(!) length modifier]code


You also need to know about operator precedence:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

and the special casing of tuples:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting



For trivial cases, format() isn't much harder than %:

"{0}".format(x)
"%s" % x

For more complex cases, format() will let you do things that you can't do
with only %, e.g. arbitrary fill characters, centring fields, percentage
formatting, mixing positional and keyword arguments, etc.

Before you blow yet another gasket, go read the PEP:

http://www.python.org/dev/peps/pep-3101/
 
S

Steven D'Aprano

There clearly is a need for a more heavyweight formatting solution than
% and string.Template. There are things that can't be done easily with %
alone, and format() will make them much simpler. I have no objection to
the addition of the format() method (although I wonder whether it might
have been better as a function).

Except of course there is a format() function. Like len(), str() etc, it
just calls the appropriate special method on the argument:

format(obj, format_spec) -> obj.__format__(format_spec)
 
S

Steve Holden

Steven said:
Debated by who? The entire Python-using community? Every single Python
programmer? Or just the small proportion of Python developers who are
also core developers?

Are you *really* surprised that some people had never heard of the
changes being debated until it was too late?
It isn't the least surprising that some people have been taken by
surprise by the changes. Neither is it surprising that some of them
don't like the changes that much. However, at least in the open source
world one has the *opportunity* to make one's voice heard and one's
opinion known, even thought he majority prefer to remain consumers of
the output of open source projects.

Where commercial projects are concerned the major influence one has is a
post-facto vote with one's wallet.

I hope, however, that those who don't like the changes but didn't bother
to track developments don't feel in any way disenfranchised. They are
still welcome to make their input, and of course there is nothing to
stop them keeping Python 2.X alive for as long as they wish.

[misconception about print's role]
Of course it could be. You just needed to write your own formatting
engine. What you mean is that it couldn't be done with % formatting and
nothing else.




There clearly is a need for a more heavyweight formatting solution than %
and string.Template. There are things that can't be done easily with %
alone, and format() will make them much simpler. I have no objection to
the addition of the format() method (although I wonder whether it might
have been better as a function).
That's doubtless a debate that will play for a long time, with no really
clear advantage either way. Programmers just like to debate these
things. Of course it's a trivial addition:

def format(s, *args, **kw):
return s.format(*args, **kw)

[I put **kw in becuase it's easier than checking the docs to se whether
keyword arguments are specified]. This doesn't mean there won't be
fifteen more posts on this thread about it.

regards
Steve
 
S

Steve Holden

Steven said:
Debated by who? The entire Python-using community? Every single Python
programmer? Or just the small proportion of Python developers who are
also core developers?

Are you *really* surprised that some people had never heard of the
changes being debated until it was too late?
It isn't the least surprising that some people have been taken by
surprise by the changes. Neither is it surprising that some of them
don't like the changes that much. However, at least in the open source
world one has the *opportunity* to make one's voice heard and one's
opinion known, even thought he majority prefer to remain consumers of
the output of open source projects.

Where commercial projects are concerned the major influence one has is a
post-facto vote with one's wallet.

I hope, however, that those who don't like the changes but didn't bother
to track developments don't feel in any way disenfranchised. They are
still welcome to make their input, and of course there is nothing to
stop them keeping Python 2.X alive for as long as they wish.

[misconception about print's role]
Of course it could be. You just needed to write your own formatting
engine. What you mean is that it couldn't be done with % formatting and
nothing else.




There clearly is a need for a more heavyweight formatting solution than %
and string.Template. There are things that can't be done easily with %
alone, and format() will make them much simpler. I have no objection to
the addition of the format() method (although I wonder whether it might
have been better as a function).
That's doubtless a debate that will play for a long time, with no really
clear advantage either way. Programmers just like to debate these
things. Of course it's a trivial addition:

def format(s, *args, **kw):
return s.format(*args, **kw)

[I put **kw in becuase it's easier than checking the docs to se whether
keyword arguments are specified]. This doesn't mean there won't be
fifteen more posts on this thread about it.

regards
Steve
 
R

rdmurray

Quoth Steven D'Aprano said:
Whether using % or format(), I don't see the need to change the code,
only the strings.

Using positional arguments is not really that different:

"{0} {1}".format("dead", "parrot")
"{0} {1}".format("perroquet", "mort")

This should be something like:

_("{0} {1}").format(_("dead"), _("parrot"))

where il8n would substitute the template "{1} {0}" when doing French.
versus:

"%s %s" % ("dead", "parrot")
"%s %s" % ("perroquet", "mort")

In this case, the template on the left remains the same, you just have to
reorder the string arguments on the right. Clearly less satisfactory than
the solution using keyword substitution, but whatever solution you pick,
I don't see any advantage to format() over % formatting. Can you show an
example?

Not less satisfactory, but rather unworkable. You can't do proper il8n
with %s formatting, since there is no way for the il8n machinery to
reorder the argument tuple. It can only translate the template string.
So when doing il8n, the {} syntax wins out for brevity over the equivalent
% syntax (%s(somename)s).

Not that brevity is that important an argument. The new system is just
so much more flexible than the old. As someone else said, the design
is beautiful :) I have a couple thousand lines of python code I wrote
a while back to layer on a system with this kind of flexibility...I was
shocked and pleased when I saw the PEP, since it echoed so many of the
ideas I had implemented in that code, plus more. And all done better
of course :)

--RDM
 
R

r

If Python is so important to you it's a pity you haven't been playing
any active role in its development. Do you expect the developers to be
psychic?

Steve,
I just recently started to have an opinion about these things. "The
squeaky wheel get the grease", just allowing my voice be heard. It
might seem that i am trashing Python dev, but that could not be
further from the truth.

Many great changes have been made in 3.0, i just feel strongly about C
style formating. Why could't we improve on what we had instead of
making radical changes? Thats all i am asking.
 
S

Stefan Behnel

Steven said:
I have no objection to
the addition of the format() method (although I wonder whether it might
have been better as a function).

I actually learned about the String.format() method in Java a while after
having read about str.format() in Python, and my first reaction was to
recognise how stupid you'd have to be to make that a static method that
ignores the string it's called on. :)

I think '...'.format() makes sense given that we already have '...'.join().

Stefan
 
M

Marc 'BlackJack' Rintsch

Marc,
Why move away from a concise and widely accepted way of sting
formatting, just to supposedly make it a little easier for n00bs? (which
i disagree this is easier) In turn, creating more syntactical clutter.
(%s %f %d) is all you need to remember. If people can't understand that,
i fear for the future of Humans as a species!

Yeah, doomsday is near. Curly brackets and a number instead of a percent
sign followed by an 's' is a sure sign of the end…

You're a funny little troll, Sir.

Ciao,
Marc 'BlackJack' Rintsch
 
S

Steve Holden

Stefan Behnel wrote:
[...]
I think '...'.format() makes sense given that we already have '...'.join().
Sure it does, but that doesn't stop a lot of people disliking str.join()

regards
Steve
 
S

Steve Holden

r said:
Steve,
I just recently started to have an opinion about these things. "The
squeaky wheel get the grease", just allowing my voice be heard. It
might seem that i am trashing Python dev, but that could not be
further from the truth.

Many great changes have been made in 3.0, i just feel strongly about C
style formating. Why could't we improve on what we had instead of
making radical changes? Thats all i am asking.

I wasn't really a part of the decision-making process, but I anticipate
that the developers' reply would be that the new scheme is much more
adaptable, both to new data types (which can implement their own
__format__ method) and to internationalization (because it's possible to
alter word order in the format strings).

Thanks for clarifying your approach, by the way, which isn't as
unreasonable as it first seemed if you've only recently started using
Python. You will find over time that the developers are right about
these decisions much more than they are wrong, and you still have a
couple of years to get used to it ;-)

regards
Steve
 
W

walterbyrd

Also, I like having only *one* special symbol (`%') to worry
about in my strings instead of two (`{' and `}').

Actually the new way has, at least three special symbols: ( '{', '}' ,
'.') as well as the method name "format" so

"%s=%s" % (k, v) for k, v in params.items()

becomes:

"{0}={1}".format((k, v) for k, v in params.items())

or something like that.
 
W

walterbyrd

Personally the new string formatter is sorely needed in Python.  

Really? You know, it's funny, but when I read problems that people
have with python, I don't remember seeing that. Loads of people
complain about the white space issue. Some people complain about the
speed. Lots of complaints about certain quirky behavior, but I have
not come across any complaints about the string formatting.

In fact, from what I have seen, many of the "problems" being "fixed"
seem to be non-problems.

I dunno, maybe it's just me.
 
R

r

Walter,

Would you be kind enough to translate this code to the new syntax?
'python 00012 1.33'

i want to see how casting is handled. Thanks
 
W

walterbyrd

Regarding the speed of Python3 programs,
they will go faster

"The net result of the 3.0 generalizations is that Python 3.0 runs the
pystone benchmark around 10% slower than Python 2.5. "

http://docs.python.org/dev/3.0/whatsnew/3.0.html
(Ruby programs are often slower
than Python ones (because Ruby
is a little higher level than Python)

As I understand it, that may have been true at one time. But, Ruby 1.9
very significantly sped up the language. While Python has been made
slower, Ruby has been made much faster.

I am no expert on the subject, I am just going by stuff I have read on
web.
 
W

walterbyrd

Walter,

Would you be kind enough to translate this code to the new syntax?

I am sorry, but I just don't know the new syntax well enough. I am not
sure if the examples that I have posted, so far, are correct.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,088
Latest member
JeremyMedl

Latest Threads

Top