Desperate need for enhanced print function

Hi! This is my first time I'm sending an email to the python-ideas mailing list. I've got an enhancement idea for the built-in print function and I hope it is as good as I think it is. Imagine you have a trial.py file like this: a = 4 b = "Anand" print("Hello, I am " + b + ". My favorite number is " + str(a) + ".") OR print("Hello, I am ", b, ". My favorite number is ", a, ".") Well I've got an idea for a function named "print_easy" (The only valid name I could come up with right now). So print_easy will be a function which will be used like this (instead of the current print statement in trial.py) : print_easy("Hello, I am", b, ". My favorite number is", a ".") Which gives out: Hello, I am Anand. My favorite number is 4 The work it does is that it casts the variables and it also formats the sentences it is provided with. It is exclusively for beginners. I'm 14 and I came up with this idea after seeing my fellow classmates at school struggling to do something like this with the standard print statement. Sure, you can use the format method but won't that be a bit too much for beginners? (Also, casting is inevitable in every programmer's career) Please let me know how this sounds. If it gains some traction, I'll work on it a bit more and clearly list out the features. Thanks, Anand. -- Anand.

On 9/5/2015 3:33 PM, Anand Krishnakumar wrote:
This prints Hello, I am Anand . My favorite number is 4 . because the sep parameter defaults to ' '. If you want 'ease', leave out end spaces within quotes and don't worry about spaces before periods. To get what you want, add ", sep=''" before the closing parenthesis. print("Hello, I am ", b, ". My favorite number is ", a, ".", sep='') Hello, I am Anand. My favorite number is 4.
Well I've got an idea for a function named "print_easy" (The only valid name I could come up with right now).
When you want a mix of '' and ' ' separators, learn to use templates. print("Hello, I am {}. My favorite number is {}.".format(b, a)) Hello, I am Anand. My favorite number is 4. This ends up being easier to type and read because is does not have all the extraneous unprinted commas and quotes in the middle. The formatting could also be written print("Hello, I am {name}. My favorite number is {favnum}." .format(name=b, favnum=a)) -- Terry Jan Reedy

On Sep 5, 2015, at 12:33, Anand Krishnakumar <anandkrishnakumar123@gmail.com> wrote:
The work it does is that it casts the variables and it also formats the sentences it is provided with. It is exclusively for beginners.
What do you mean by "casts"? The print function already calls str on each of its arguments. Do you want print_easy to do something different? If so, what? And why do you call it "casting"? More generally, how do you want the output of print_easy to differ from the output of print, given the same arguments? If you're hoping it can automatically figure out where to put spaces and where not to, what rule do you want it to use? Obviously it can't be some complicated DWIM AI that figures out whether you're writing English sentences, German sentences, a columnar table, or source code, but maybe there's something simple you can come up with that's still broadly useful. (If you can figure out how to turn that into code, you can put print_easy up on PyPI and let people get some experience using it and increase the chances of getting buy-in to the idea, and even if everyone rejects it as a builtin, you and other students can still use it.)

On 6 September 2015 at 05:33, Anand Krishnakumar <anandkrishnakumar123@gmail.com> wrote:
Hi Anand, Your feedback reflects a common point of view on the surprising difficulty of producing nicely formatted messages from Python code. As such, it currently appears likely that Python 3.6 will allow you and your peers to write output messages like this: print(f"Hello, I am {b}. My favorite number is {a}.") as a simpler alternative to the current options: print("Hello, I am ", b, ". My favorite number is ", a, ".", sep="") print("Hello, I am " + b + ". My favorite number is " + str(a) + ".") print("Hello, I am {}. My favorite number is {}.".format(b, a)) print("Hello, I am {b}. My favorite number is {a}.".format_map(locals())) print("Hello, I am %s. My favorite number is %s." % (b, a)) Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 07.09.2015 01:48, Nick Coghlan wrote:
Wow, that is awesome and awkward at the same time. Shouldn't Python 3.7 deprecate at least some of them? (Just looking at the Zen of Python and https://xkcd.com/927/ ) Best, Sven

On Mon, Sep 7, 2015 at 3:46 PM, Sven R. Kunze <srkunze@mail.de> wrote:
Which would you deprecate? print("Hello, I am ", b, ". My favorite number is ", a, ".", sep="") The print function stringifies all its arguments and outputs them, joined by a separator. Aside from the 2/3 compatibility requirement for single-argument print calls, there's no particular reason to deprecate this. In any case, this isn't "yet another way to format strings", it's a feature of print. print("Hello, I am " + b + ". My favorite number is " + str(a) + ".") String concatenation is definitely not going away; but even without PEP 498, I would prefer to use percent formatting or .format() above this. Its main advantage over those is that the expressions are in the right place, which PEP 498 also offers; if it lands, I fully expect 3.6+ code to use it rather than this. But the _functionality_ can't be taken away. print("Hello, I am {}. My favorite number is {}.".format(b, a)) This one is important for non-literals. It's one of the two main ways of formatting strings... print("Hello, I am %s. My favorite number is %s." % (b, a)) ... and this is the other. Being available for non-literals means they can be used with i18n, string tables, and other transformations. Percent formatting is similar to what other C-derived languages have, and .format() has certain flexibilities, so neither is likely to be deprecated any time soon. print("Hello, I am {b}. My favorite number is {a}.".format_map(locals())) This one, though, is a bad idea for several reasons. Using locals() for formatting is restricted - no globals, no expressions, and no nonlocals that aren't captured in some other way. If this one, and this one alone, can be replaced by f-string usage, it's done its job. ChrisA

On Mon, Sep 07, 2015 at 06:23:13PM +1000, Chris Angelico wrote:
print("Hello, I am {b}. My favorite number is {a}.".format_map(locals()))
This one, though, is a bad idea for several reasons.
Such as what?
That's a feature, not a bug. locals(), by definition, only includes locals. If you want globals, non-locals, built-ins, expressions, or the kitchen sink, you can't get them from locals(). Just because the locals() trick doesn't handle every possible scenario doesn't make it a bad idea for those cases it does handle, any more than it is a bad idea to use 2**5 just because the ** operator doesn't handle the 3-argument form of pow(). I probably wouldn't use the locals() form if the variable names were hard-coded like that, especially for just two of them: "Hello, I am {b}. My favorite number is {a}.".format(a=a, b=b) Where the locals() trick comes in handy is when your template string is not hard-coded: if greet: template = "Hello, I am {name}, and my favourite %s is {%s}." else: template = "My favourite %s is {%s}." if condition: template = template % ("number", "x") else: template = template % ("colour", "c") print(template.format_map(locals()) -- Steve

On Mon, Sep 7, 2015 at 10:19 PM, Steven D'Aprano <steve@pearwood.info> wrote:
It's still a poor equivalent for the others. In terms of "why do we have so many different ways to do the same thing", the response is "the good things to do with format_map(locals()) are not the things you can do with f-strings". If what you're looking for can be done with either, it's almost certainly not better to use locals(). ChrisA

On 09/07/2015 07:21 AM, Chris Angelico wrote:
The ability for a format string or template to take a mapping is very useful. Weather or not it's ok for that mapping to be from locals() is a separate issue and depends on other factors as well. It may be perfectly fine in some cases, but not so in others. The issue with + concatenation is it doesn't call str on the objects. That can't be changed. A new operator (or methods on str) that does that could work. It's still not as concise as f-strings which I think is a major motivation for having them. Cheers, Ron

On Tue, Sep 8, 2015 at 3:32 AM, Ron Adam <ron3200@gmail.com> wrote:
I think that's the most we're ever going to have in terms of deprecations. None of the _functionality_ of any of the examples will be going away, but some of them will be non-recommended ways of doing certain things. I definitely agree that taking format values from a mapping is useful. ChrisA

On 07.09.2015 10:23, Chris Angelico wrote:
Which would you deprecate?
Hard to tell. Let me see what you got me here. Remember, I am just asking as I don't know better:
Still necessary?
For sure, however that shouldn't be used in the official documentation if so now, right?
Still necessary? Really, really necessary? Or just because we can?
and .format() has certain flexibilities, so neither is likely to be deprecated any time soon.
format has its own merits as it works like f-strings but on non-literals. (again this one-way/one-syntax thing)
Well sure, I we all agree on not using that until f-strings are released. Best, Sven

Sven R. Kunze <srkunze@...> writes:
There are many conservative Python users who are probably underrepresented on this list. All can say is that %-formatting never went out of fashion, see e.g. https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Streams , https://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Strings , https://golang.org/pkg/fmt/ and many others. Fortunately, there are no plans to deprecate %-formatting (latest reference is PEP-498). Stefan Krah

On Sep 7, 2015, at 11:57, Sven R. Kunze <srkunze@mail.de> wrote:
There's some confusion over this because the str.format proposal originally suggested deprecating %, and there are still some bloggers and StackOverflow users and so on that claim it does (sometimes even citing the PEP, which explicitly says the opposite). But there will always be cases that % is better for, such as: * sharing a table of format strings with code in C or another language * simple formats that need to be done fast in a loop * formatting strings to use as str.format format strings * messages that you've converted from logging to real output * ASCII-based wire protocols or file formats So, even if it weren't for the backward compatibility issue for millions of lines of old code (and thousands of stubborn old coders), I doubt it would ever go away. At most, the tutorial and other docs might change to de-emphasize it and make it seem more like an "expert" feature only useful for cases like the above (as is already true for string.Template, and may become true for both % and str.format after f-strings reach widespread use--but nobody can really predict that until f-strings are actually in practical use). TOOWTDI is a guideline that has to balance against other guidelines, not a strict rule that always trumps everything else, and unless someone can come up with something new that's so much better than both format and % that it's clearly worth overcoming the inertia rather than just being a case of the old standards joke (insert XKCD reference here), there will be two ways to do this.

On Tue, Sep 8, 2015 at 7:00 AM, Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
Supporting this last one is PEP 461. There are no proposals on the cards to add a b"...".format() method (it's not out of the question, but there are problems to be overcome because of the extreme generality of it), yet we have percent formatting for bytestrings. I think that's a strong indication that percent formatting is fully supported and will be for the future. ChrisA

Chris Angelico writes:
[...]
Actually, it was proposed and pronounced (immediately on proposal :-). There were no truly difficult technical problems, but Guido decided it was a YAGNI, and often an attractive nuisance. In particular, many of the use cases for bytestring formatting are performance-critical bit- shoveling applications, and adding a few extra method lookups and calls to every formatting operation would be a problem. Many others involve porting Python 2 applications that used str to hold and format "external" strings, and those use %-formatting, not .format.
because of the extreme generality of it),
Hm. It seems to me in the PEP 498 discussion that Guido doesn't see generality as a problem to be solved by restricting it, but rather as a characteristic of an implementation that makes it more or less suitable for a given feature. I guess that Guido would insist on having bytes.format be almost identical to str.format, except maybe for a couple of tweaks similar to those added to bytes' % operator.

On Sep 7, 2015, at 09:48, Sven R. Kunze <srkunze@mail.de> wrote:
Necessary? No. Useful? Yes. For example, in a 5-line script I wrote last night, I've got print(head, *names, sep='\t'). I could have used print('\t'.join(chain([head], names)) instead--in fact, any use of multi-argument print can be replaced by print(sep.join(map(str, args)))--but that's less convenient, less readable, and less likely to occur to novices. And there are plenty of other alternatives, from print('{}\t{}'.format(head, '\t'.join(names)) to print(('%s\t'*(len(names)+1) % ((head,)+names))[:-1]) to that favorite of novices on Stack Overflow, print(str([head]+names)[1:-1].replace(', ', '\t')), but would you really want to use any of these? Or course in a "real program" that I needed to use more than once, I would have used the csv module instead of a 5-line script driven by a 3-line shell script, and there's a limit to how far you want to push the argument for quick&dirty scripting/interactive convenience... but that limit isn't "none at all". When you start trying to mix manual adding of spaces with sep='' to get a sentence formatted exactly right, that's a good sign that you should be using format instead of multi-arg print; when you start trying to add up format strings, that's a good sign you should be using either something simpler or something more complicated. That is an extra thing novices have to get the hang of to become proficient Python programmers that doesn't exist for C or Perl. But the fact that you _can_ use Python like C, but don't have to, isn't really a downside of Python.

On Mon, 07 Sep 2015 17:39:26 -0500, Ryan Gonzalez wrote:
On September 7, 2015 3:52:52 PM CDT, Random832 <random832@fastmail.com> wrote:
t = (1, 2, 3) # 400 lines later t *= 4 # oops? Why do you (Ryan Gonzalez) have names that are important enough to span over 400 lines of source code but not important enough to call something more interesting than "t"? And why are we conflating the print function with string formatting with natural language translation in the first place?

On September 7, 2015 6:13:49 PM CDT, Dan Sommers <dan@tombstonezero.net> wrote:
You're blowing this out of proportion. I was simply showing how string formatting can be *weird* when it comes to tuples.
-- Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.

Ryan Gonzalez <rymg19@gmail.com> writes:
I always use % (t,) when intending to format a single object. But anyway, my ideal version of it would have a .format method, but using identical format strings. My real question was what the benefit of the {}-format for format strings is, over an extended %-format.

On 8 September 2015 at 09:28, Random832 <random832@fastmail.com> wrote:
It turns out PEP 3101 doesn't really go into this, so I guess it was a case where all of us involved in the discussion knew the reasons a new format was needed, so we never wrote them down. As such, it's worth breaking the problem down into a few different subproblems: 1. Invocation via __mod__ 2. Positional formatting 3. Name based formatting 4. Extending formatting to new types in an extensible, backwards compatible way The problems with formatting dictionaries and tuples relate to the "fmt % values" invocation model, rather than the substitution field syntax. As such, we *could* have designed str.format() and str.format_map() around %-interpolation. The reasons we chose not to do that relate to the other problems. For positional formatting of short strings, %-interpolation actually works pretty well, and it has the advantage of being consistent with printf() style APIs in C and C++. This is the use case where it has proven most difficult to get people to switch away from mod-formatting, and is also the approach we used to restore binary interpolation support in Python 3.5. An illustrative example is to compare formatting a floating point number to use 2 decimal places: >>> x = y = 1.0 >>> "%.2f, %.2f" % (x, y) '1.00, 1.00' >>> "{:.2f}, {:.2f}".format(x, y) '1.00, 1.00' I consider the second example there to be *less* readable than the original mod-formatting. These kinds of cases are why we *changed our mind* from "we'd like to deprecate mod-formatting, but we haven't figured out a practical way to do so" to "mod-formatting and brace-formatting are better at different things, so it's actually useful having both of them available". For name based formatting, by contrast, the "%(name)s" syntax is noisy and clumsy compared to the shorter "{name}" format introduced in PEP 3101 (borrowed from C#). There the value has been clear, and so folks have been significantly more amenable to switching away from mod-formatting: >>> "%(x).2f, %(y).2f" % dict(x=x, y=y) '1.00, 1.00' >>> "{x:.2f}, {y:.2f}".format(x=x, y=y) '1.00, 1.00' It's that last example which PEP 498 grants native syntax, with the entire trailing method call being replaced by a simple leading "f": >>> f"{x:.2f}, {y:.2f}" '1.00, 1.00' This gets us back to TOOWTDI (after a long detour away from it), since direct interpolation will clearly be the obvious way to go when interpolating into a literal format string - the other options will only be needed when literal formatting isn't appropriate for some reason. The final reason for introducing a distinct formatting system doesn't relate to syntax, but rather to semantics. Mod-formatting is defined around the builtin types, with "__str__" as the catch-all fallback for interpolating arbitrary objects. PEP 3101 introduced a new *protocol* method (__format__) that allowed classes more control over how their instances were formatted, with the typical example being to allow dates and times to accept strftime formatting strings directly rather than having to make a separate strftime call prior to formatting. Python generally follows a philosophy of "constructs with different semantics should use different syntax" (at least in the core language design), which is reflected in the fact that a new formatting syntax was introduced in conjunction with a new formatting protocol. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan <ncoghlan@gmail.com> writes:
I guess my problem is that I don't consider the fact that %s forces something to string, %f to float, etc, to be desired semantics, I consider it to be a bug that could, and *should*, have been changed by an alternate-universe PEP. There's nothing *good* about the fact that '%.20f' % Decimal('0.1') gives 0.10000000000000000555 instead of 0.10000000000000000000, and that there are no hooks for Decimal to make it do otherwise. There's nothing that would IMO be legitimately broken by allowing it to do so. You could, for example, have object.__format__ fall back on the type conversion semantics, so that it would continue to work with existing types that do not define their own __format__.

On 8 September 2015 at 11:46, Random832 <random832@fastmail.com> wrote:
Ah, but there *is* something good about it: the fact that percent-formatting is restricted to a constrained set of known types makes it fundamentally more *predictable* and more *portable* than brace-formatting. The flexibility of str.format is wonderful if you're only needing to deal with Python code, and Python's type system. It's substantially less wonderful if you're designing formatting operations that need to span multiple languages that only have the primitive core defined by C in common. These characteristics are what make percent-formatting a more suitable approach to binary interpolation than the fully flexible formatting system. Binary interpolation is not only really hard to do right, it's also really hard to *test* - many of the things that can go wrong are driven by the specific data values you choose to test with, rather than being structural errors in the data types you use. These benefits aren't particularly obvious until you try to live without them and figure out why you missed them, but we *have* done that in the 7 years since 2.6 was released, and hence have a good understanding of why brace-formatting wasn't the wholesale replacement for percent-formatting that we originally expected it to be. That said, there *have* been ongoing efforts to improve the numeric formatting capabilities of printf and related operations in C/C++ that we haven't been tracking at the Python level. In relation to decimal support specifically, the C++ write-up at http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3871.html also links to the C level proposal and the proposed changes to the interpretation of the floating point codes when working with decimal data types. However, as far as I am aware, there isn't anyone specifically tracking the evolution of printf() formatting codes and reviewing them for applicability to Python's percent-formatting support - it's done more in an ad hoc fashion as folks developing in both Python and C/C++ start using a new formatting code on the C/C++ side of things and request that it also be added to Python. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

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.

"Stephen J. Turnbull" <stephen@xemacs.org> writes:
By "Identical" I meant there would be a single mechanism, including all new features, used for both str.format and str.__mod__ - i.e. the extensions would also be available using the % operator. The extensions would be implemented, but the % operator would not be left behind. Hence, identical.

On Sep 8, 2015, at 12:39, random832@fastmail.us wrote:
I think it's already been established why % formatting is not going away any time soon. As for de-emphasizing it, I think that's already done pretty well in the current docs. The tutorial has a nice long introduction to str.format, a one-paragraph section on "old string formatting" with a single %5.3f example, and a one-sentence mention of Template. The stdtypes chapter in the library reference explains the difference between the two in a way that makes format sound more attractive for novices, and then has details on each one as appropriate. What else should be done?

On 09.09.2015 02:09, Andrew Barnert via Python-ideas wrote:
I think it's already been established why % formatting is not going away any time soon.
As for de-emphasizing it, I think that's already done pretty well in the current docs. The tutorial has a nice long introduction to str.format, a one-paragraph section on "old string formatting" with a single %5.3f example, and a one-sentence mention of Template. The stdtypes chapter in the library reference explains the difference between the two in a way that makes format sound more attractive for novices, and then has details on each one as appropriate. What else should be done?
I had difficulties to find what you mean by tutorial. But hey, being a Python user for years and not knowing where the official tutorial resides... Anyway, Google presented me the version 2.7 of the tutorial. Thus, the link to the stdtypes documentation does not exhibit the note of, say, 3.5: "Note: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer str.format() interface helps avoid these errors, and also provides a generally more powerful, flexible and extensible approach to formatting text." So, adding it to the 2.7 docs would be a start. I still don't understand what's wrong with deprecating %, but okay. I think f-strings will push {} to wide-range adoption. Best, Sven

Sven R. Kunze <srkunze@...> writes:
I still don't understand what's wrong with deprecating %, but okay. I think f-strings will push {} to wide-range adoption.
Then it will probably be hard to explain, so I'll be direct: 1) Many Python users are fed up with churn and don't want to do yet another rewrite of their applications (just after migrating to 3.x). 2) Despite many years of officially preferring {}-formatting in the docs (and on Stackoverflow), people *still* use %-formatting. This should be a clue that they actually like it. 3) %-formatting often has better performance and is often easier to read. 4) Yes, in other cases {}-formatting is easier to read. So choose whatever is best. Stefan Krah

On Sep 9, 2015, at 09:05, Sven R. Kunze <srkunze@mail.de> wrote:
If you go to docs.python.org (directly, or by clicking the link to docs for Python 3 or Python 2 from the home page or the documentation menu), Tutorial is the second thing on the list, after What's New. And, as you found, it's the first hit for "Python tutorial" on Google. At any rate, if you're not concerned with the tutorial, which parts of the docs are you worried about? Sure, a lot of people learn Python from various books, websites, and classes that present % instead of (or at least in equal light with) {}, but those are all outside the control of Python itself. You can't write a PEP to get the author of ThinkPython, a guy who wrote 1800 random StackOverflow answers, or the instructor for Programming 101 at Steve University to change what they teach. And if not the docs, what else would it mean to "de-emphasize" %-formatting without deprecating or removing it?
Anyway, Google presented me the version 2.7 of the tutorial.
That's a whole other problem. But nobody is going to retroactively change Python 2.7 just to help people who find the 2.7 docs when they should be looking for 3.5. That might seem reasonable today, when 2.7 could heartily recommend str.format because it's nearly the same in 2.7 as in 3.5, but what about next year, when f-strings are the preferred way to do it in 3.6? If 3.6 de-emphasizes str.format (as a feature used only when you need backward compat and/or dynamic formats) and its tutorial, %-formatting docs, and str.format docs all point to f-strings, having 2.7's docs point people to str.format will be misleading at best for 3.6, but having it recommend something that doesn't exist in 2.7 will be actively wrong for 2.7. The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
I still don't understand what's wrong with deprecating %, but okay.
Well, have you read the answers given by Nick, me, and others earlier in the thread? If so, what do you disagree with? You've only addressed one point (that % is faster than {} for simple cases--and your solution is just "make {} faster", which may not be possible given that it's inherently more hookable than % and therefore requires more function calls...). What about formatting headers for ASCII wire protocols, sharing tables of format strings between programming languages (e.g., for i18n), or any of the other reasons people have brought up?

On 09.09.2015 23:50, Andrew Barnert wrote:
And if not the docs, what else would it mean to "de-emphasize" %-formatting without deprecating or removing it?
The docs are most important. Sorry, if that didn't come across clearly.
Anyway, Google presented me the version 2.7 of the tutorial. That's a whole other problem. But nobody is going to retroactively change Python 2.7 just to help people who find the 2.7 docs when they should be looking for 3.5.
The Python docs are not Python. So, what's in the way of adding this note to Python 2.7 docs? The pride of the Python core devs? I anticipate better of you.
That might seem reasonable today, when 2.7 could heartily recommend str.format because it's nearly the same in 2.7 as in 3.5, but what about next year, when f-strings are the preferred way to do it in 3.6? If 3.6 de-emphasizes str.format (as a feature used only when you need backward compat and/or dynamic formats) and its tutorial, %-formatting docs, and str.format docs all point to f-strings, having 2.7's docs point people to str.format will be misleading at best for 3.6, but having it recommend something that doesn't exist in 2.7 will be actively wrong for 2.7.
str.format teaches people how to use {}. That should be encouraged. Switching from str.format to f-strings is going to work like charm. So, it's the syntax I am concerned with, not how to execute the magic behind.
The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
You have absolutely no idea why people use 2.7 over 3.5, right? I promise you that is going to take time. And what could you do in the meantime? Call it hacking; to me it's improving.
I still don't understand what's wrong with deprecating %, but okay. Well, have you read the answers given by Nick, me, and others earlier in the thread? If so, what do you disagree with?
All "blockers" I read so far classify as a) personal preference of % over {} or b) fixable. Both classes do not qualify as real blockers; they can be overcome.
You've only addressed one point (that % is faster than {} for simple cases--and your solution is just "make {} faster", which may not be possible given that it's inherently more hookable than % and therefore requires more function calls...).
Try harder. (If {} is too slow for you.) I've read Python 3 is significantly slower than Python 2. So what? I can live with that, when we will make the transition. If we recognize the performance penalty, rest assured I come back here to seek your advice but until that it's no reason not to switch to Python 3. Same goes for string formatting.
What about formatting headers for ASCII wire protocols, sharing tables of format strings between programming languages (e.g., for i18n), or any of the other reasons people have brought up? Both fixable in some way or another, the rest classifies as described above.
Best, Sven

On Sep 9, 2015, at 15:45, Sven R. Kunze <srkunze@mail.de> wrote:
No problem.
First, the Python docs are part of Python. They're owned by the same foundation, managed by the same team, and updated with a similar process. Second, I'm not a core dev, and since the Python docs are maintained by the core devs, that stands in the way of me personally making that change. :) Of course I can easily file a docs bug, with a patch, and possibly start a discussion on the relevant list to get wider discussion. But you can do that as easily as I can, and I don't know why you should anticipate better of me than you do of yourself. (If you don't feel capable of writing the change, because you're not a native speaker or your tech writing skills aren't as good as your coding skills or whatever, I won't argue that your English seems good enough to me; just write a "draft" patch and then ask for people to improve it. There are docs changes that have been done this way in the past, and I think there are more than enough people who'd be happy to help.)
The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
You have absolutely no idea why people use 2.7 over 3.5, right? I promise you that is going to take time.
Of course I don't know why _every_ person still using 2.7 is doing so. For myself personally, off the top of my head, recent reasons have included: maintaining an existing, working app that wouldn't gain any benefit from upgrading it; writing a simple script to be deployed on servers that have 2.7 pre-installed; and writing portable libraries to share on PyPI that work on both 2.7 and 3.3+ to make them useful to as many devs as possible. I know other people do it for similarly good reasons, or different ones (e.g., depending on some library that hasn't been ported yet), and also for bad reasons (related to outdated teaching materials or FUD or depending on some library that has been ported but they checked a 6-year-old blog instead of current information). I know that we're still a few years away from the end of the initial transition period, so none of this surprises me much. But how is any of that, or any additional factors I don't know about, relevant to the fact that using the 2.7 docs (and especially the tutorial) when coding for 3.5 is a bad idea, and a problem to be fixed? How does any of it mean that making the 2.7 docs apply better to 3.5 but worse to 2.7 is a solution?
Just saying "I want % deprecated, and I declare that all of the apparent blocking problems are solvable, and therefore I demand that someone else solve them and then deprecate %" is not very useful. If you think that's the way Python should go, come up with solutions for all of the ones that need to be fixed (and file bugs and ideally patches), and good arguments to dismiss the ones you don't think need to be fixed. Then you can argue that the only remaining reason not to deprecate % is backward compatibility, which isn't compelling enough, and that may well convince everyone.

On 10.09.2015 01:14, Andrew Barnert wrote:
Of course I can easily file a docs bug, with a patch, and possibly start a discussion on the relevant list to get wider discussion. But you can do that as easily as I can, and I don't know why you should anticipate better of me than you do of yourself. (If you don't feel capable of writing the change, because you're not a native speaker or your tech writing skills aren't as good as your coding skills or whatever, I won't argue that your English seems good enough to me; just write a "draft" patch and then ask for people to improve it. There are docs changes that have been done this way in the past, and I think there are more than enough people who'd be happy to help.)
I didn't know that. The Python development and discussion process is still somewhat opaque to me. Btw. you asked for what could be improved and I responded. :) Best, Sven

On 2015-09-09 14:50, Andrew Barnert via Python-ideas wrote:
This getting off on a tangent, but I don't see most of those as super compelling. Any programming language can use whatever formatting scheme it likes. Keeping %-substitutions around helps in sharing format strings only with other languages that use exactly the same formatting style. So it's not like % has any intrinsic gain; it just happens to interoperate with some other particular stuff. That's nice, but I don't think it makes sense to keep things in Python just so it can interoperate in specific ways with specific other languages that use less-readable syntax. To me the main advantage of {} is it's more readable. Readability is relevant in any application. The other things you're mentioning seem to be basically about making certain particular applications easier, and I see that as less important. In other words, if to write a wire protocol or share format strings you have to write your own functions to do stuff in a more roundabout way instead of using a (or the!) built-in formatting mechanism, I'm fine with that if it streamlines the built-in formatting mechanism(s). (The main DISadvantage of {} so far is that its readability is limited because you have to pass in all that stuff with the format call at the end. I think if one of these string-interpolation PEPs settles down and we get something like "I like {this} and {that}" --- where the names are drawn directly from the enclosing scope without having to pass them in --- that will be a huge win over both the existing {} formatting and the % formatting.) -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown

On 10 September 2015 at 12:07, Brendan Barnwell <brenbarn@brenbarn.net> wrote:
This perspective doesn't grant enough credit to the significance of C in general, and the C ABI in particular, in the overall computing landscape. While a lot of folks have put a lot of work into making it possible to write software without needing to learn the details of what's happening at the machine level, it's still the case that the *one* language binding interface that *every* language runtime ends up including is being able to load and run C libraries. It's also the case that for any new CPU architecture, one of the first things people will do is bootstrap a C compiler for it, as that then lets them bootstrap a whole host of other things (including Python). For anyone that wants to make the transition from high level programming to low level programming, or vice-versa, C is also the common language understood by both software developers and computer systems engineers. There *are* some worthy contenders out there that may eventually topple C's permissive low level memory access model from its position of dominance (I personally have high hopes for Rust), but that's not going to be a quick process. Regards, Nick. P.S. It's also worth remembering than many Pythonistas, including members of the core development team, happily switch between programming languages according to the task at hand. Python can still be our *preferred* language without becoming the *only* language we use :) -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10.09.2015 17:36, Nick Coghlan wrote:
Ah, now I understand. We need to add {} to C. That'll make it, right? ;) Seriously, there are also other significant influences that fit better here: template engines. I know a couple of them using {} in some sense or another. C format strings are just one of them, so I wouldn't stress the significance of C that hard *in that particular instance*. There are other areas where C has its strengths.
I hope everybody on this list knows that.:) Best, Sven

On 11 September 2015 at 03:35, Sven R. Kunze <srkunze@mail.de> wrote:
You're tilting at windmills Sven. Python has 3 substitution variable syntaxes (two with builtin support), and we no longer have any plans for getting rid of any of them. We *did* aim to deprecate percent-substitution as part of the Python 3 migration, and after trying for ~5 years *decided that was a bad idea*, and reversed the original decision to classify it as deprecated. We subsequently switched the relevant section of the docs from describing percent-formatting as "old string formatting" to "printf-style string formatting" in a larger revamp of the builtin sequence type documentation a few years back: https://hg.python.org/cpython/rev/463f52d20314 PEP 461 has now further entrenched the notion that "percent-formatting is recommended for binary data, brace-formatting is recommended for text data" by bringing back the former for bytes and bytearray in 3.5, while leaving str.format as text only: https://www.python.org/dev/peps/pep-0461/ PEP 498 then blesses brace-formatting as the "one obvious way" for text formatting by elevating it from "builtin method" to "syntax" in 3.6. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I use %-formatting. Not because I think it's so wonderful and solves all problems (although it's pretty good), but because it appeared to be the recommended method at the time I learned Python in earnest. If I were only learning Python now, I would probably learn str.format or whatever it is. I *could* learn to use something else *and* change all my working code, but do you really want to force me to do that? I would guess that there are quite a lot of Python users in the same position. Rob Cliffe On 09/09/2015 17:05, Sven R. Kunze wrote:

Of course I would not want to force you, Rob. I believe in progress and progress is achieved through change. So, the best method for change I know of are deprecations: not all changes come bundled but singly and with time to prepare. To me, it's just a minor deficiency in Python's own vision. Best, Sven On 10.09.2015 01:32, Rob Cliffe wrote:

random832@fastmail.us writes:
My take is: Having two format string grammars is worse than having one, even if the %-grammar is worse than the {}-grammar.
The same has been said for having two (or more) loop grammars. Where have you gone, Repeat Until A nation turns its lonely eyes to you What's that you say, Mrs Robinson Pascal itself has turned to Modula 2 (or 3) (how 'bout 4?!) The point is that not all experiments can be contained in a single personal branch posted to GitHub. (Kudos to Trent who seems to be pulling off that trick as we controverse. Even if it's possible it's not necessarily easy!) We all agree in isolation with the value you express (more or less TOOWTDI), but it's the balance of many desiderata that makes Python a great language. But that balance clearly is against you: At the time {}-formatting was introduced, there had already been several less-than-wildly-successful experiments (including string.Template), yet the PEP was nevertheless accepted. In string formatting, the consensus is evidently that it's difficult enough to measure improvement objectively that sufficiently plausible experiments will still be admitted into the stdlib (or not, in the case of the much-delayed PEP 461 -- way to go, Ethan! -- the decision *not* to have backward compatible formatting for bytestrings was itself an experiment in this sense). And it's a difficult enough design space that the principle of minimal sufficient change (implicit in what you're saying) was not strictly applied to {}-formatting (or string.Template, for that matter). I'm not just being ornery, string formatting is near and dear to my heart. I'm genuinely curious why you choose a much more conservative balance in this area than Python has. But to my eyes your posts so far amount to an attempted wake-up call: "TOOWTDI is more important in string formatting than you all seem to think!" and no more. Sincere regards,

On 07.09.2015 01:48, Nick Coghlan wrote:
No need to wait for Python 3.6. Since print is a function, you can easily override it using your own little helper to make things easier for you. And this works in all Python versions starting with Python 2.6: """ # For Python 2 you need to make print a function first: from __future__ import print_function import sys _orig_print = print # Use .format() as basis for print() def fprint(template, *args, **kws): caller = sys._getframe(1) context = caller.f_locals _orig_print(template.format(**context), *args, **kws) # Use C-style %-formatting as basis for print() def printf(template, *args, **kws): caller = sys._getframe(1) context = caller.f_locals _orig_print(template % context, *args, **kws) # Examples: a = 1 fprint('a = {a}') printf('a = %(a)s') # Let's use fprint() as standard print() in this module: print = fprint b = 3 print('b = {b}') """ -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Sep 07 2015)
2015-08-27: Released eGenix mx Base 3.2.9 ... http://egenix.com/go83 2015-09-18: PyCon UK 2015 ... 11 days to go ::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/

On 9/5/2015 3:33 PM, Anand Krishnakumar wrote:
This prints Hello, I am Anand . My favorite number is 4 . because the sep parameter defaults to ' '. If you want 'ease', leave out end spaces within quotes and don't worry about spaces before periods. To get what you want, add ", sep=''" before the closing parenthesis. print("Hello, I am ", b, ". My favorite number is ", a, ".", sep='') Hello, I am Anand. My favorite number is 4.
Well I've got an idea for a function named "print_easy" (The only valid name I could come up with right now).
When you want a mix of '' and ' ' separators, learn to use templates. print("Hello, I am {}. My favorite number is {}.".format(b, a)) Hello, I am Anand. My favorite number is 4. This ends up being easier to type and read because is does not have all the extraneous unprinted commas and quotes in the middle. The formatting could also be written print("Hello, I am {name}. My favorite number is {favnum}." .format(name=b, favnum=a)) -- Terry Jan Reedy

On Sep 5, 2015, at 12:33, Anand Krishnakumar <anandkrishnakumar123@gmail.com> wrote:
The work it does is that it casts the variables and it also formats the sentences it is provided with. It is exclusively for beginners.
What do you mean by "casts"? The print function already calls str on each of its arguments. Do you want print_easy to do something different? If so, what? And why do you call it "casting"? More generally, how do you want the output of print_easy to differ from the output of print, given the same arguments? If you're hoping it can automatically figure out where to put spaces and where not to, what rule do you want it to use? Obviously it can't be some complicated DWIM AI that figures out whether you're writing English sentences, German sentences, a columnar table, or source code, but maybe there's something simple you can come up with that's still broadly useful. (If you can figure out how to turn that into code, you can put print_easy up on PyPI and let people get some experience using it and increase the chances of getting buy-in to the idea, and even if everyone rejects it as a builtin, you and other students can still use it.)

On 6 September 2015 at 05:33, Anand Krishnakumar <anandkrishnakumar123@gmail.com> wrote:
Hi Anand, Your feedback reflects a common point of view on the surprising difficulty of producing nicely formatted messages from Python code. As such, it currently appears likely that Python 3.6 will allow you and your peers to write output messages like this: print(f"Hello, I am {b}. My favorite number is {a}.") as a simpler alternative to the current options: print("Hello, I am ", b, ". My favorite number is ", a, ".", sep="") print("Hello, I am " + b + ". My favorite number is " + str(a) + ".") print("Hello, I am {}. My favorite number is {}.".format(b, a)) print("Hello, I am {b}. My favorite number is {a}.".format_map(locals())) print("Hello, I am %s. My favorite number is %s." % (b, a)) Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 07.09.2015 01:48, Nick Coghlan wrote:
Wow, that is awesome and awkward at the same time. Shouldn't Python 3.7 deprecate at least some of them? (Just looking at the Zen of Python and https://xkcd.com/927/ ) Best, Sven

On Mon, Sep 7, 2015 at 3:46 PM, Sven R. Kunze <srkunze@mail.de> wrote:
Which would you deprecate? print("Hello, I am ", b, ". My favorite number is ", a, ".", sep="") The print function stringifies all its arguments and outputs them, joined by a separator. Aside from the 2/3 compatibility requirement for single-argument print calls, there's no particular reason to deprecate this. In any case, this isn't "yet another way to format strings", it's a feature of print. print("Hello, I am " + b + ". My favorite number is " + str(a) + ".") String concatenation is definitely not going away; but even without PEP 498, I would prefer to use percent formatting or .format() above this. Its main advantage over those is that the expressions are in the right place, which PEP 498 also offers; if it lands, I fully expect 3.6+ code to use it rather than this. But the _functionality_ can't be taken away. print("Hello, I am {}. My favorite number is {}.".format(b, a)) This one is important for non-literals. It's one of the two main ways of formatting strings... print("Hello, I am %s. My favorite number is %s." % (b, a)) ... and this is the other. Being available for non-literals means they can be used with i18n, string tables, and other transformations. Percent formatting is similar to what other C-derived languages have, and .format() has certain flexibilities, so neither is likely to be deprecated any time soon. print("Hello, I am {b}. My favorite number is {a}.".format_map(locals())) This one, though, is a bad idea for several reasons. Using locals() for formatting is restricted - no globals, no expressions, and no nonlocals that aren't captured in some other way. If this one, and this one alone, can be replaced by f-string usage, it's done its job. ChrisA

On Mon, Sep 07, 2015 at 06:23:13PM +1000, Chris Angelico wrote:
print("Hello, I am {b}. My favorite number is {a}.".format_map(locals()))
This one, though, is a bad idea for several reasons.
Such as what?
That's a feature, not a bug. locals(), by definition, only includes locals. If you want globals, non-locals, built-ins, expressions, or the kitchen sink, you can't get them from locals(). Just because the locals() trick doesn't handle every possible scenario doesn't make it a bad idea for those cases it does handle, any more than it is a bad idea to use 2**5 just because the ** operator doesn't handle the 3-argument form of pow(). I probably wouldn't use the locals() form if the variable names were hard-coded like that, especially for just two of them: "Hello, I am {b}. My favorite number is {a}.".format(a=a, b=b) Where the locals() trick comes in handy is when your template string is not hard-coded: if greet: template = "Hello, I am {name}, and my favourite %s is {%s}." else: template = "My favourite %s is {%s}." if condition: template = template % ("number", "x") else: template = template % ("colour", "c") print(template.format_map(locals()) -- Steve

On Mon, Sep 7, 2015 at 10:19 PM, Steven D'Aprano <steve@pearwood.info> wrote:
It's still a poor equivalent for the others. In terms of "why do we have so many different ways to do the same thing", the response is "the good things to do with format_map(locals()) are not the things you can do with f-strings". If what you're looking for can be done with either, it's almost certainly not better to use locals(). ChrisA

On 09/07/2015 07:21 AM, Chris Angelico wrote:
The ability for a format string or template to take a mapping is very useful. Weather or not it's ok for that mapping to be from locals() is a separate issue and depends on other factors as well. It may be perfectly fine in some cases, but not so in others. The issue with + concatenation is it doesn't call str on the objects. That can't be changed. A new operator (or methods on str) that does that could work. It's still not as concise as f-strings which I think is a major motivation for having them. Cheers, Ron

On Tue, Sep 8, 2015 at 3:32 AM, Ron Adam <ron3200@gmail.com> wrote:
I think that's the most we're ever going to have in terms of deprecations. None of the _functionality_ of any of the examples will be going away, but some of them will be non-recommended ways of doing certain things. I definitely agree that taking format values from a mapping is useful. ChrisA

On 07.09.2015 10:23, Chris Angelico wrote:
Which would you deprecate?
Hard to tell. Let me see what you got me here. Remember, I am just asking as I don't know better:
Still necessary?
For sure, however that shouldn't be used in the official documentation if so now, right?
Still necessary? Really, really necessary? Or just because we can?
and .format() has certain flexibilities, so neither is likely to be deprecated any time soon.
format has its own merits as it works like f-strings but on non-literals. (again this one-way/one-syntax thing)
Well sure, I we all agree on not using that until f-strings are released. Best, Sven

Sven R. Kunze <srkunze@...> writes:
There are many conservative Python users who are probably underrepresented on this list. All can say is that %-formatting never went out of fashion, see e.g. https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Streams , https://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Strings , https://golang.org/pkg/fmt/ and many others. Fortunately, there are no plans to deprecate %-formatting (latest reference is PEP-498). Stefan Krah

On Sep 7, 2015, at 11:57, Sven R. Kunze <srkunze@mail.de> wrote:
There's some confusion over this because the str.format proposal originally suggested deprecating %, and there are still some bloggers and StackOverflow users and so on that claim it does (sometimes even citing the PEP, which explicitly says the opposite). But there will always be cases that % is better for, such as: * sharing a table of format strings with code in C or another language * simple formats that need to be done fast in a loop * formatting strings to use as str.format format strings * messages that you've converted from logging to real output * ASCII-based wire protocols or file formats So, even if it weren't for the backward compatibility issue for millions of lines of old code (and thousands of stubborn old coders), I doubt it would ever go away. At most, the tutorial and other docs might change to de-emphasize it and make it seem more like an "expert" feature only useful for cases like the above (as is already true for string.Template, and may become true for both % and str.format after f-strings reach widespread use--but nobody can really predict that until f-strings are actually in practical use). TOOWTDI is a guideline that has to balance against other guidelines, not a strict rule that always trumps everything else, and unless someone can come up with something new that's so much better than both format and % that it's clearly worth overcoming the inertia rather than just being a case of the old standards joke (insert XKCD reference here), there will be two ways to do this.

On Tue, Sep 8, 2015 at 7:00 AM, Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
Supporting this last one is PEP 461. There are no proposals on the cards to add a b"...".format() method (it's not out of the question, but there are problems to be overcome because of the extreme generality of it), yet we have percent formatting for bytestrings. I think that's a strong indication that percent formatting is fully supported and will be for the future. ChrisA

Chris Angelico writes:
[...]
Actually, it was proposed and pronounced (immediately on proposal :-). There were no truly difficult technical problems, but Guido decided it was a YAGNI, and often an attractive nuisance. In particular, many of the use cases for bytestring formatting are performance-critical bit- shoveling applications, and adding a few extra method lookups and calls to every formatting operation would be a problem. Many others involve porting Python 2 applications that used str to hold and format "external" strings, and those use %-formatting, not .format.
because of the extreme generality of it),
Hm. It seems to me in the PEP 498 discussion that Guido doesn't see generality as a problem to be solved by restricting it, but rather as a characteristic of an implementation that makes it more or less suitable for a given feature. I guess that Guido would insist on having bytes.format be almost identical to str.format, except maybe for a couple of tweaks similar to those added to bytes' % operator.

On Sep 7, 2015, at 09:48, Sven R. Kunze <srkunze@mail.de> wrote:
Necessary? No. Useful? Yes. For example, in a 5-line script I wrote last night, I've got print(head, *names, sep='\t'). I could have used print('\t'.join(chain([head], names)) instead--in fact, any use of multi-argument print can be replaced by print(sep.join(map(str, args)))--but that's less convenient, less readable, and less likely to occur to novices. And there are plenty of other alternatives, from print('{}\t{}'.format(head, '\t'.join(names)) to print(('%s\t'*(len(names)+1) % ((head,)+names))[:-1]) to that favorite of novices on Stack Overflow, print(str([head]+names)[1:-1].replace(', ', '\t')), but would you really want to use any of these? Or course in a "real program" that I needed to use more than once, I would have used the csv module instead of a 5-line script driven by a 3-line shell script, and there's a limit to how far you want to push the argument for quick&dirty scripting/interactive convenience... but that limit isn't "none at all". When you start trying to mix manual adding of spaces with sep='' to get a sentence formatted exactly right, that's a good sign that you should be using format instead of multi-arg print; when you start trying to add up format strings, that's a good sign you should be using either something simpler or something more complicated. That is an extra thing novices have to get the hang of to become proficient Python programmers that doesn't exist for C or Perl. But the fact that you _can_ use Python like C, but don't have to, isn't really a downside of Python.

On Mon, 07 Sep 2015 17:39:26 -0500, Ryan Gonzalez wrote:
On September 7, 2015 3:52:52 PM CDT, Random832 <random832@fastmail.com> wrote:
t = (1, 2, 3) # 400 lines later t *= 4 # oops? Why do you (Ryan Gonzalez) have names that are important enough to span over 400 lines of source code but not important enough to call something more interesting than "t"? And why are we conflating the print function with string formatting with natural language translation in the first place?

On September 7, 2015 6:13:49 PM CDT, Dan Sommers <dan@tombstonezero.net> wrote:
You're blowing this out of proportion. I was simply showing how string formatting can be *weird* when it comes to tuples.
-- Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.

Ryan Gonzalez <rymg19@gmail.com> writes:
I always use % (t,) when intending to format a single object. But anyway, my ideal version of it would have a .format method, but using identical format strings. My real question was what the benefit of the {}-format for format strings is, over an extended %-format.

On 8 September 2015 at 09:28, Random832 <random832@fastmail.com> wrote:
It turns out PEP 3101 doesn't really go into this, so I guess it was a case where all of us involved in the discussion knew the reasons a new format was needed, so we never wrote them down. As such, it's worth breaking the problem down into a few different subproblems: 1. Invocation via __mod__ 2. Positional formatting 3. Name based formatting 4. Extending formatting to new types in an extensible, backwards compatible way The problems with formatting dictionaries and tuples relate to the "fmt % values" invocation model, rather than the substitution field syntax. As such, we *could* have designed str.format() and str.format_map() around %-interpolation. The reasons we chose not to do that relate to the other problems. For positional formatting of short strings, %-interpolation actually works pretty well, and it has the advantage of being consistent with printf() style APIs in C and C++. This is the use case where it has proven most difficult to get people to switch away from mod-formatting, and is also the approach we used to restore binary interpolation support in Python 3.5. An illustrative example is to compare formatting a floating point number to use 2 decimal places: >>> x = y = 1.0 >>> "%.2f, %.2f" % (x, y) '1.00, 1.00' >>> "{:.2f}, {:.2f}".format(x, y) '1.00, 1.00' I consider the second example there to be *less* readable than the original mod-formatting. These kinds of cases are why we *changed our mind* from "we'd like to deprecate mod-formatting, but we haven't figured out a practical way to do so" to "mod-formatting and brace-formatting are better at different things, so it's actually useful having both of them available". For name based formatting, by contrast, the "%(name)s" syntax is noisy and clumsy compared to the shorter "{name}" format introduced in PEP 3101 (borrowed from C#). There the value has been clear, and so folks have been significantly more amenable to switching away from mod-formatting: >>> "%(x).2f, %(y).2f" % dict(x=x, y=y) '1.00, 1.00' >>> "{x:.2f}, {y:.2f}".format(x=x, y=y) '1.00, 1.00' It's that last example which PEP 498 grants native syntax, with the entire trailing method call being replaced by a simple leading "f": >>> f"{x:.2f}, {y:.2f}" '1.00, 1.00' This gets us back to TOOWTDI (after a long detour away from it), since direct interpolation will clearly be the obvious way to go when interpolating into a literal format string - the other options will only be needed when literal formatting isn't appropriate for some reason. The final reason for introducing a distinct formatting system doesn't relate to syntax, but rather to semantics. Mod-formatting is defined around the builtin types, with "__str__" as the catch-all fallback for interpolating arbitrary objects. PEP 3101 introduced a new *protocol* method (__format__) that allowed classes more control over how their instances were formatted, with the typical example being to allow dates and times to accept strftime formatting strings directly rather than having to make a separate strftime call prior to formatting. Python generally follows a philosophy of "constructs with different semantics should use different syntax" (at least in the core language design), which is reflected in the fact that a new formatting syntax was introduced in conjunction with a new formatting protocol. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan <ncoghlan@gmail.com> writes:
I guess my problem is that I don't consider the fact that %s forces something to string, %f to float, etc, to be desired semantics, I consider it to be a bug that could, and *should*, have been changed by an alternate-universe PEP. There's nothing *good* about the fact that '%.20f' % Decimal('0.1') gives 0.10000000000000000555 instead of 0.10000000000000000000, and that there are no hooks for Decimal to make it do otherwise. There's nothing that would IMO be legitimately broken by allowing it to do so. You could, for example, have object.__format__ fall back on the type conversion semantics, so that it would continue to work with existing types that do not define their own __format__.

On 8 September 2015 at 11:46, Random832 <random832@fastmail.com> wrote:
Ah, but there *is* something good about it: the fact that percent-formatting is restricted to a constrained set of known types makes it fundamentally more *predictable* and more *portable* than brace-formatting. The flexibility of str.format is wonderful if you're only needing to deal with Python code, and Python's type system. It's substantially less wonderful if you're designing formatting operations that need to span multiple languages that only have the primitive core defined by C in common. These characteristics are what make percent-formatting a more suitable approach to binary interpolation than the fully flexible formatting system. Binary interpolation is not only really hard to do right, it's also really hard to *test* - many of the things that can go wrong are driven by the specific data values you choose to test with, rather than being structural errors in the data types you use. These benefits aren't particularly obvious until you try to live without them and figure out why you missed them, but we *have* done that in the 7 years since 2.6 was released, and hence have a good understanding of why brace-formatting wasn't the wholesale replacement for percent-formatting that we originally expected it to be. That said, there *have* been ongoing efforts to improve the numeric formatting capabilities of printf and related operations in C/C++ that we haven't been tracking at the Python level. In relation to decimal support specifically, the C++ write-up at http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3871.html also links to the C level proposal and the proposed changes to the interpretation of the floating point codes when working with decimal data types. However, as far as I am aware, there isn't anyone specifically tracking the evolution of printf() formatting codes and reviewing them for applicability to Python's percent-formatting support - it's done more in an ad hoc fashion as folks developing in both Python and C/C++ start using a new formatting code on the C/C++ side of things and request that it also be added to Python. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

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.

"Stephen J. Turnbull" <stephen@xemacs.org> writes:
By "Identical" I meant there would be a single mechanism, including all new features, used for both str.format and str.__mod__ - i.e. the extensions would also be available using the % operator. The extensions would be implemented, but the % operator would not be left behind. Hence, identical.

On Sep 8, 2015, at 12:39, random832@fastmail.us wrote:
I think it's already been established why % formatting is not going away any time soon. As for de-emphasizing it, I think that's already done pretty well in the current docs. The tutorial has a nice long introduction to str.format, a one-paragraph section on "old string formatting" with a single %5.3f example, and a one-sentence mention of Template. The stdtypes chapter in the library reference explains the difference between the two in a way that makes format sound more attractive for novices, and then has details on each one as appropriate. What else should be done?

On 09.09.2015 02:09, Andrew Barnert via Python-ideas wrote:
I think it's already been established why % formatting is not going away any time soon.
As for de-emphasizing it, I think that's already done pretty well in the current docs. The tutorial has a nice long introduction to str.format, a one-paragraph section on "old string formatting" with a single %5.3f example, and a one-sentence mention of Template. The stdtypes chapter in the library reference explains the difference between the two in a way that makes format sound more attractive for novices, and then has details on each one as appropriate. What else should be done?
I had difficulties to find what you mean by tutorial. But hey, being a Python user for years and not knowing where the official tutorial resides... Anyway, Google presented me the version 2.7 of the tutorial. Thus, the link to the stdtypes documentation does not exhibit the note of, say, 3.5: "Note: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer str.format() interface helps avoid these errors, and also provides a generally more powerful, flexible and extensible approach to formatting text." So, adding it to the 2.7 docs would be a start. I still don't understand what's wrong with deprecating %, but okay. I think f-strings will push {} to wide-range adoption. Best, Sven

Sven R. Kunze <srkunze@...> writes:
I still don't understand what's wrong with deprecating %, but okay. I think f-strings will push {} to wide-range adoption.
Then it will probably be hard to explain, so I'll be direct: 1) Many Python users are fed up with churn and don't want to do yet another rewrite of their applications (just after migrating to 3.x). 2) Despite many years of officially preferring {}-formatting in the docs (and on Stackoverflow), people *still* use %-formatting. This should be a clue that they actually like it. 3) %-formatting often has better performance and is often easier to read. 4) Yes, in other cases {}-formatting is easier to read. So choose whatever is best. Stefan Krah

On Sep 9, 2015, at 09:05, Sven R. Kunze <srkunze@mail.de> wrote:
If you go to docs.python.org (directly, or by clicking the link to docs for Python 3 or Python 2 from the home page or the documentation menu), Tutorial is the second thing on the list, after What's New. And, as you found, it's the first hit for "Python tutorial" on Google. At any rate, if you're not concerned with the tutorial, which parts of the docs are you worried about? Sure, a lot of people learn Python from various books, websites, and classes that present % instead of (or at least in equal light with) {}, but those are all outside the control of Python itself. You can't write a PEP to get the author of ThinkPython, a guy who wrote 1800 random StackOverflow answers, or the instructor for Programming 101 at Steve University to change what they teach. And if not the docs, what else would it mean to "de-emphasize" %-formatting without deprecating or removing it?
Anyway, Google presented me the version 2.7 of the tutorial.
That's a whole other problem. But nobody is going to retroactively change Python 2.7 just to help people who find the 2.7 docs when they should be looking for 3.5. That might seem reasonable today, when 2.7 could heartily recommend str.format because it's nearly the same in 2.7 as in 3.5, but what about next year, when f-strings are the preferred way to do it in 3.6? If 3.6 de-emphasizes str.format (as a feature used only when you need backward compat and/or dynamic formats) and its tutorial, %-formatting docs, and str.format docs all point to f-strings, having 2.7's docs point people to str.format will be misleading at best for 3.6, but having it recommend something that doesn't exist in 2.7 will be actively wrong for 2.7. The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
I still don't understand what's wrong with deprecating %, but okay.
Well, have you read the answers given by Nick, me, and others earlier in the thread? If so, what do you disagree with? You've only addressed one point (that % is faster than {} for simple cases--and your solution is just "make {} faster", which may not be possible given that it's inherently more hookable than % and therefore requires more function calls...). What about formatting headers for ASCII wire protocols, sharing tables of format strings between programming languages (e.g., for i18n), or any of the other reasons people have brought up?

On 09.09.2015 23:50, Andrew Barnert wrote:
And if not the docs, what else would it mean to "de-emphasize" %-formatting without deprecating or removing it?
The docs are most important. Sorry, if that didn't come across clearly.
Anyway, Google presented me the version 2.7 of the tutorial. That's a whole other problem. But nobody is going to retroactively change Python 2.7 just to help people who find the 2.7 docs when they should be looking for 3.5.
The Python docs are not Python. So, what's in the way of adding this note to Python 2.7 docs? The pride of the Python core devs? I anticipate better of you.
That might seem reasonable today, when 2.7 could heartily recommend str.format because it's nearly the same in 2.7 as in 3.5, but what about next year, when f-strings are the preferred way to do it in 3.6? If 3.6 de-emphasizes str.format (as a feature used only when you need backward compat and/or dynamic formats) and its tutorial, %-formatting docs, and str.format docs all point to f-strings, having 2.7's docs point people to str.format will be misleading at best for 3.6, but having it recommend something that doesn't exist in 2.7 will be actively wrong for 2.7.
str.format teaches people how to use {}. That should be encouraged. Switching from str.format to f-strings is going to work like charm. So, it's the syntax I am concerned with, not how to execute the magic behind.
The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
You have absolutely no idea why people use 2.7 over 3.5, right? I promise you that is going to take time. And what could you do in the meantime? Call it hacking; to me it's improving.
I still don't understand what's wrong with deprecating %, but okay. Well, have you read the answers given by Nick, me, and others earlier in the thread? If so, what do you disagree with?
All "blockers" I read so far classify as a) personal preference of % over {} or b) fixable. Both classes do not qualify as real blockers; they can be overcome.
You've only addressed one point (that % is faster than {} for simple cases--and your solution is just "make {} faster", which may not be possible given that it's inherently more hookable than % and therefore requires more function calls...).
Try harder. (If {} is too slow for you.) I've read Python 3 is significantly slower than Python 2. So what? I can live with that, when we will make the transition. If we recognize the performance penalty, rest assured I come back here to seek your advice but until that it's no reason not to switch to Python 3. Same goes for string formatting.
What about formatting headers for ASCII wire protocols, sharing tables of format strings between programming languages (e.g., for i18n), or any of the other reasons people have brought up? Both fixable in some way or another, the rest classifies as described above.
Best, Sven

On Sep 9, 2015, at 15:45, Sven R. Kunze <srkunze@mail.de> wrote:
No problem.
First, the Python docs are part of Python. They're owned by the same foundation, managed by the same team, and updated with a similar process. Second, I'm not a core dev, and since the Python docs are maintained by the core devs, that stands in the way of me personally making that change. :) Of course I can easily file a docs bug, with a patch, and possibly start a discussion on the relevant list to get wider discussion. But you can do that as easily as I can, and I don't know why you should anticipate better of me than you do of yourself. (If you don't feel capable of writing the change, because you're not a native speaker or your tech writing skills aren't as good as your coding skills or whatever, I won't argue that your English seems good enough to me; just write a "draft" patch and then ask for people to improve it. There are docs changes that have been done this way in the past, and I think there are more than enough people who'd be happy to help.)
The solution is to get people to the 3.5 or 3.6 docs in the first place, not to hack up the 2.7 docs.
You have absolutely no idea why people use 2.7 over 3.5, right? I promise you that is going to take time.
Of course I don't know why _every_ person still using 2.7 is doing so. For myself personally, off the top of my head, recent reasons have included: maintaining an existing, working app that wouldn't gain any benefit from upgrading it; writing a simple script to be deployed on servers that have 2.7 pre-installed; and writing portable libraries to share on PyPI that work on both 2.7 and 3.3+ to make them useful to as many devs as possible. I know other people do it for similarly good reasons, or different ones (e.g., depending on some library that hasn't been ported yet), and also for bad reasons (related to outdated teaching materials or FUD or depending on some library that has been ported but they checked a 6-year-old blog instead of current information). I know that we're still a few years away from the end of the initial transition period, so none of this surprises me much. But how is any of that, or any additional factors I don't know about, relevant to the fact that using the 2.7 docs (and especially the tutorial) when coding for 3.5 is a bad idea, and a problem to be fixed? How does any of it mean that making the 2.7 docs apply better to 3.5 but worse to 2.7 is a solution?
Just saying "I want % deprecated, and I declare that all of the apparent blocking problems are solvable, and therefore I demand that someone else solve them and then deprecate %" is not very useful. If you think that's the way Python should go, come up with solutions for all of the ones that need to be fixed (and file bugs and ideally patches), and good arguments to dismiss the ones you don't think need to be fixed. Then you can argue that the only remaining reason not to deprecate % is backward compatibility, which isn't compelling enough, and that may well convince everyone.

On 10.09.2015 01:14, Andrew Barnert wrote:
Of course I can easily file a docs bug, with a patch, and possibly start a discussion on the relevant list to get wider discussion. But you can do that as easily as I can, and I don't know why you should anticipate better of me than you do of yourself. (If you don't feel capable of writing the change, because you're not a native speaker or your tech writing skills aren't as good as your coding skills or whatever, I won't argue that your English seems good enough to me; just write a "draft" patch and then ask for people to improve it. There are docs changes that have been done this way in the past, and I think there are more than enough people who'd be happy to help.)
I didn't know that. The Python development and discussion process is still somewhat opaque to me. Btw. you asked for what could be improved and I responded. :) Best, Sven

On 2015-09-09 14:50, Andrew Barnert via Python-ideas wrote:
This getting off on a tangent, but I don't see most of those as super compelling. Any programming language can use whatever formatting scheme it likes. Keeping %-substitutions around helps in sharing format strings only with other languages that use exactly the same formatting style. So it's not like % has any intrinsic gain; it just happens to interoperate with some other particular stuff. That's nice, but I don't think it makes sense to keep things in Python just so it can interoperate in specific ways with specific other languages that use less-readable syntax. To me the main advantage of {} is it's more readable. Readability is relevant in any application. The other things you're mentioning seem to be basically about making certain particular applications easier, and I see that as less important. In other words, if to write a wire protocol or share format strings you have to write your own functions to do stuff in a more roundabout way instead of using a (or the!) built-in formatting mechanism, I'm fine with that if it streamlines the built-in formatting mechanism(s). (The main DISadvantage of {} so far is that its readability is limited because you have to pass in all that stuff with the format call at the end. I think if one of these string-interpolation PEPs settles down and we get something like "I like {this} and {that}" --- where the names are drawn directly from the enclosing scope without having to pass them in --- that will be a huge win over both the existing {} formatting and the % formatting.) -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown

On 10 September 2015 at 12:07, Brendan Barnwell <brenbarn@brenbarn.net> wrote:
This perspective doesn't grant enough credit to the significance of C in general, and the C ABI in particular, in the overall computing landscape. While a lot of folks have put a lot of work into making it possible to write software without needing to learn the details of what's happening at the machine level, it's still the case that the *one* language binding interface that *every* language runtime ends up including is being able to load and run C libraries. It's also the case that for any new CPU architecture, one of the first things people will do is bootstrap a C compiler for it, as that then lets them bootstrap a whole host of other things (including Python). For anyone that wants to make the transition from high level programming to low level programming, or vice-versa, C is also the common language understood by both software developers and computer systems engineers. There *are* some worthy contenders out there that may eventually topple C's permissive low level memory access model from its position of dominance (I personally have high hopes for Rust), but that's not going to be a quick process. Regards, Nick. P.S. It's also worth remembering than many Pythonistas, including members of the core development team, happily switch between programming languages according to the task at hand. Python can still be our *preferred* language without becoming the *only* language we use :) -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 10.09.2015 17:36, Nick Coghlan wrote:
Ah, now I understand. We need to add {} to C. That'll make it, right? ;) Seriously, there are also other significant influences that fit better here: template engines. I know a couple of them using {} in some sense or another. C format strings are just one of them, so I wouldn't stress the significance of C that hard *in that particular instance*. There are other areas where C has its strengths.
I hope everybody on this list knows that.:) Best, Sven

On 11 September 2015 at 03:35, Sven R. Kunze <srkunze@mail.de> wrote:
You're tilting at windmills Sven. Python has 3 substitution variable syntaxes (two with builtin support), and we no longer have any plans for getting rid of any of them. We *did* aim to deprecate percent-substitution as part of the Python 3 migration, and after trying for ~5 years *decided that was a bad idea*, and reversed the original decision to classify it as deprecated. We subsequently switched the relevant section of the docs from describing percent-formatting as "old string formatting" to "printf-style string formatting" in a larger revamp of the builtin sequence type documentation a few years back: https://hg.python.org/cpython/rev/463f52d20314 PEP 461 has now further entrenched the notion that "percent-formatting is recommended for binary data, brace-formatting is recommended for text data" by bringing back the former for bytes and bytearray in 3.5, while leaving str.format as text only: https://www.python.org/dev/peps/pep-0461/ PEP 498 then blesses brace-formatting as the "one obvious way" for text formatting by elevating it from "builtin method" to "syntax" in 3.6. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I use %-formatting. Not because I think it's so wonderful and solves all problems (although it's pretty good), but because it appeared to be the recommended method at the time I learned Python in earnest. If I were only learning Python now, I would probably learn str.format or whatever it is. I *could* learn to use something else *and* change all my working code, but do you really want to force me to do that? I would guess that there are quite a lot of Python users in the same position. Rob Cliffe On 09/09/2015 17:05, Sven R. Kunze wrote:

Of course I would not want to force you, Rob. I believe in progress and progress is achieved through change. So, the best method for change I know of are deprecations: not all changes come bundled but singly and with time to prepare. To me, it's just a minor deficiency in Python's own vision. Best, Sven On 10.09.2015 01:32, Rob Cliffe wrote:

random832@fastmail.us writes:
My take is: Having two format string grammars is worse than having one, even if the %-grammar is worse than the {}-grammar.
The same has been said for having two (or more) loop grammars. Where have you gone, Repeat Until A nation turns its lonely eyes to you What's that you say, Mrs Robinson Pascal itself has turned to Modula 2 (or 3) (how 'bout 4?!) The point is that not all experiments can be contained in a single personal branch posted to GitHub. (Kudos to Trent who seems to be pulling off that trick as we controverse. Even if it's possible it's not necessarily easy!) We all agree in isolation with the value you express (more or less TOOWTDI), but it's the balance of many desiderata that makes Python a great language. But that balance clearly is against you: At the time {}-formatting was introduced, there had already been several less-than-wildly-successful experiments (including string.Template), yet the PEP was nevertheless accepted. In string formatting, the consensus is evidently that it's difficult enough to measure improvement objectively that sufficiently plausible experiments will still be admitted into the stdlib (or not, in the case of the much-delayed PEP 461 -- way to go, Ethan! -- the decision *not* to have backward compatible formatting for bytestrings was itself an experiment in this sense). And it's a difficult enough design space that the principle of minimal sufficient change (implicit in what you're saying) was not strictly applied to {}-formatting (or string.Template, for that matter). I'm not just being ornery, string formatting is near and dear to my heart. I'm genuinely curious why you choose a much more conservative balance in this area than Python has. But to my eyes your posts so far amount to an attempted wake-up call: "TOOWTDI is more important in string formatting than you all seem to think!" and no more. Sincere regards,

On 07.09.2015 01:48, Nick Coghlan wrote:
No need to wait for Python 3.6. Since print is a function, you can easily override it using your own little helper to make things easier for you. And this works in all Python versions starting with Python 2.6: """ # For Python 2 you need to make print a function first: from __future__ import print_function import sys _orig_print = print # Use .format() as basis for print() def fprint(template, *args, **kws): caller = sys._getframe(1) context = caller.f_locals _orig_print(template.format(**context), *args, **kws) # Use C-style %-formatting as basis for print() def printf(template, *args, **kws): caller = sys._getframe(1) context = caller.f_locals _orig_print(template % context, *args, **kws) # Examples: a = 1 fprint('a = {a}') printf('a = %(a)s') # Let's use fprint() as standard print() in this module: print = fprint b = 3 print('b = {b}') """ -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Sep 07 2015)
2015-08-27: Released eGenix mx Base 3.2.9 ... http://egenix.com/go83 2015-09-18: PyCon UK 2015 ... 11 days to go ::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
participants (17)
-
Anand Krishnakumar
-
Andrew Barnert
-
Brendan Barnwell
-
Chris Angelico
-
Dan Sommers
-
M.-A. Lemburg
-
Nick Coghlan
-
Random832
-
random832@fastmail.us
-
Rob Cliffe
-
Ron Adam
-
Ryan Gonzalez
-
Stefan Krah
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Sven R. Kunze
-
Terry Reedy