back
132 comments
String interpolation is one of those features where I'm really confused about the direction the Python team wants to take. It's implicit and magic, and yet another non-obvious way to do do string formatting.

What's more, it's being hailed at a plus for localization which it isn't. Localizers should never, ever deal with string interpolation - anything past what .format() does is essentially untranslatable.

Why is it implicit and magic? Looking at this post, and the PEP, it seems like interpolation is actually pretty close to .format in semantics, but syntactically simpler. There are a few bits that I didn't quite follow in the PEP, so I may just be missing the issue, however.
Being a die-hard Python user on a daily basis, I concur. I think these core devs should not invent too many new syntax and ways to solve problems which don't need to be added to the language.

I am not sure why i18n is a big deal, let another library deal with it.

Whatever, I have the choice not using this feature after it is accepted and implemented. Their PEP discussion on email always ended up in tangential. Problem I always have with string manipulation is dealing with long string, which for coding style I'd split into multiple +, and thus using format is pretty ugly.

I agree with you. It is already possible to use quote and plus in the same way as the bracket in the new way, with the added advantage that the original syntax is more orthogonal.

Is it really worth updating all the Python syntax formatting and analysis code out there just to save one character on an operator? I don't think it's a good tradeoff.

Someone made a good argument that in order to support lots of languages, you actually need general functions not just strings to be put into .format() or interpolation.

That's because some languages have complicated changes in the text depending on eg the number of things: not just singular/plural, but more complicated. Russian is one example.

I'm a bit confused about all the doubt on such a common feature industry wide. No, it's not magic, it's a simple transformation, takes about 30 seconds to learn, and is becoming an industry standard among modern languages. See C#, Scala, JS, Swift, etc, not to mention bash and perl.

It also has little in common with i18n, the use cases differ too much. Perhaps in the future someone can figure out how to bring them together, but not today.

From another post:

    "{a} {b} {a}".format(a=a, b=b)
    "{a} {b} {a}".format(**locals())
Compared to this:

    f"{a} {b} {a}"
Sorry that's about 1000% better. This should have been the one way to do it, originally. It isn't magic either, rather a simple compile-time transformation to existing format syntax. There's nothing new to remember besides a large reduction in noise.
I'm in the "wish it was more explicit" camp. Would a fmt function be that terrible?

    fmt("{a} {b} {c}", a=a, b=b, c=c)
If you want to save typing, maybe use :a instead of {a}. Or ?a would have made plain old ? a nice positional variant:

    fmt("?a ? ?", a=a, b, c)
The main benefit of the fmt function is that it requires no syntax changes to the language and is trivially provided by a third party library for all past versions of Python.

That being said this ship has sailed. I guess I just take a more conservative approach to syntax changes than most.

Update: a bit sad to see my votes fluctuating wildly on this post. Please don't use votes to support or disagree with me: that's not what they're for. Please vote only based on whether you find this relevant.

Some people deride string interpolation as not explicit enough, but I think it's extremely readable and adds clarity. Plus, with the `f` prefix, it's plenty explicit IMO.
String interpolation is only being added for string literals, not for generic strings. This means that you still wouldn't be able to read a template from a file, then format text in.

    with open('template.txt') as f:
        template = f.read()
    formatted = template.format(**values)
This breaks gettext translations:

  _(f"English {a} words {b} here {a}")
The interpolation is done before the string is passed to gettext which can't retrieve the translated string any more.
The motivation for PEP-0498 given in the article was the difference in verbosity between these two lines:

  "{} {}".format(a, b)
  "%s %s" % (a, b,)
That's not very convincing. I was hoping this article would make a good case for interpolated strings, since it's starting to feel like Python is having an identity crisis. Type annotations especially took me by surprise, but string interpolation is another good example of an addition that doesn't feel like Python (imho, anyway).
The more common case for me is to name the parameters. Especially with longer variable names, this gets tedious fast. Given

    >>> very_long_var_name_1 = 'spam'
    >>> very_long_var_name_2 = 'ham'
compare

    >>> # Explicit but tedious and doesn't help readability:
    >>> print('{very_long_var_name_1}: {very_long_var_name_2}'.format(
    ...       very_long_var_name_1=very_long_var_name_1,
    ...       very_long_var_name_2=very_long_var_name_2))
    spam: ham
with

    >>> # Explicit but somehow feels dirty:
    >>> print('{very_long_var_name_1}: {very_long_var_name_2}'.format(
    ...       **locals()))
    spam: ham
and

    >>> # Still fits on one line. I think f prefix makes intent clear.
    >>> print(f'{very_long_var_name_1}: {very_long_var_name_2}')
    spam: ham
I have mixed feeling about this. This will be the FOURTH way of formatting strings in Python. The other formattings will never go away.
What's the fourth way? The article only mentions three.
I think they keep the other formatting for backward compatibility in legacy code.
I'll just leave this here: https://www.python.org/dev/peps/pep-0020/

"There should be one-- and preferably only one --obvious way to do it."

There are a lot of warts on that snake, but I still really like using Python.

PEP20 sound amazing, but then when this only way end up being way too verbose/ugly, you are kind of stuck with it. Compare:

    #python
    import re
    m = re.search('(a.+)(d.+)', 'abcdef')
    if m:
      print(f"{m.group(1)},{m.group(2)}")

    #perl
    if('abcdef' =~ /(a.+)(d.+)/){
      print "$1,$2";
    }
There are a couple of warts for sure, but Python is remarkably wart free. Compare it to something wart ridden like PHP or JavaScript.
keyword is "preferably".

Also "Simple is better than complex", "practicality beats purity" and "Readability counts".

The zen is not the bible, you don't get to cherrypick the stuff you want to make your case.

Plus, they are just guide lines, in the end, you have a debate in the python dev mailing list with reasonable people making their case.

Preferably one. Unfortunately they put in `format`, and can't remove it now. I think moving towards f-strings is a lot better and should be embraced.
"Practicality beats purity."
Also not a fan. The two existing methods of string formatting are sufficient:

    "%s %s %s" % (a, b, a)
    "{} {} {}".format(a, b, a)
If you want placeholders to match variable names, you can do:

    "{a} {b} {a}".format(a=a, b=b)
    "{a} {b} {a}".format(**locals())
So this is just unnecessary (especially since the "f" prefix is easier to miss than a "format" method):

    f"{a} {b} {a}"
And this is downright obfuscated—putting operators inside of string literals:

    f"{a + ' ' + b + ' ' + a}"
I certainly agree about your last statement, I have no clue what that would do without reading the spec. I'd guess an error, but apparently not.
The PEP says that locals() and globals() solutions were considered, and discarded:

https://www.python.org/dev/peps/pep-0498/#no-use-of-globals-...

You could argue that's not a good enough reason, but it's there.

At the very least, it sure looks a hell of a lot better. And using symbols and single-character abbreviations for types (in a dynamically typed language, mind you) and an overloaded % which has the extra syntactical rule that it only takes a single argument and so multiple replacements have to be done by throwing them all into a tuple is FAR more intuitive and readable than the way most languages do string formatting. Plus the alternatives, that require you bounce back and forth between the string and the variable it is replacing rather than read left to right the way humans are meant to read strings of text is a terrible design. Something as simple as string formatting should not rely on arcane and nuanced rules which are more or less arbitrary.

You've all been programming in C-like languages for far too long to realize what a horrible design string formatting is. You can argue over "explicitness" all you want, the new way is easier to learn, easier to read, makes more intuitive sense, requires learning fewer rules, ad is close enough to the format string method that they work well together.

As an outsider to the python community and full time ruby dev, this "controversy" baffles me every time it comes up. Lightweight string interpolation is obviously better! I think you all have string Stockholm Syndrome or something.

The one counter argument that makes sense to me is that in general we shouldn't be doing easy string interpolation, since that way lies SQL injection, XSS, etc, and should instead rely on a stronger type system with binary text blobs, HtmlStrings, SqlStrings, etc, with automatic escaping into and out of the data type.

But then that's not the case with Python now. If you're only trying to stick this string inside that string in a quick and dirty manner, I totally don't understand the reticence folks have to something the way ruby does it: "Name: #{first_name}".

If it's obviously better, would you care to share some better arguments than "people who disagree have stockholm syndrome"?

Don't get me wrong, I'd like Python to have better, more obvious, more concise string formatting. However the last time we had this discussion, it was about str.format() and how it was going to be awesome and don't worry modulo-formatting will go away.

Turns out it did not; modulo formatting is still there because why would it be removed. This is history repeating itself - are you actually baffled that some people learn from past mistakes?

Not a fan. We already have 2 ways of formating strings in Python, we really should not bring in a third one.

It may be true that

    "{} {}".format(a, b)
is a bit verbose, but it is crystal clear and clean. Just remember the Python Zen: "There should be one-- and preferably only one --obvious way to do it." _and_ "Explicit is better than implicit."
It is the same thing as .format without all the noise.
Quite useful! If you want to have string interpolation in Python 2.6+ just use https://github.com/syrusakbary/interpy
“They” could put string interpolation in the __future__ module:

from __future__ import string_interpolation

:)

Am I crazy or PHP had this feature since forever? String templates can significantly improve programming speed specially for those of us who are keyboard impaired. Not having to remember how many %s' you need or if one of them should be %d and so on may to most seem just knit picking but personally it makes a day and night difference.
PHP has had it forever. Given PHP's reputation, I'm not sure if that is a good argument for this feature. Rather than '%s' and '%d', why not just use '{}' and '.format'? That way, each argument is converted to a string appropriately. If it becomes confusing with many arguments, it is easy to name the parameters '{myparam}'
> That actually looks pretty nice but as Python 3.6 is slated for release in another 12 months you will have to wait a little longer.

...Or just do it in 28 lines of Lua:

http://hisham.hm/2016/01/04/string-interpolation-in-lua/

This is a nice showcase of how Lua's metamechanisms can be applied to do things that often require new features in other languages.

I'd argue that it's not a good thing that you can just disregard block scoping willy-nilly from within unprivileged code.
I for one welcome the shorthand interpolation. String formatting is the thing we all do all day long (slightly exaggerated pretty much).

Now if python would begin to support immutable values by default then I'd be most content, and Python complete enough.

+1 for https://pyformat.info/ (mentioned in article), with some nice practical examples of equivalent %s and .format() formatting.
There should be one-- and preferably only one --obvious way to do it.

Hoping for a decision from the core team – having both f"" and .format is a pretty clear deviation from this principle.

Well, having both % and .format was already a clear deviation from it.
The rift between Python 3 and Python 2 seems to be a fallout of the one-true-way philosophy. In fact, it almost stands the reason that Python 3.6 ought to be Python 4 if one-true-way needs to be upheld.

If Python 3.6 is going to introduce multiple ways to do the same thing, there is no good reason to not merge Python 2 and 3 together and have both set of behavior co-exist with each other (__future__ or __past__).

In one shot, you break the Berlin wall of Python.

"PEP-0498 tries to improve this situation by offering something that has been common to other languages like Ruby, Scala and Perl for quite some time: Interpolated strings."

P3 '.format 'is fine, the only problem I have is forgetting the last ')' and vim picks this up. Is interpolation that good to introduce another way of doing things?

> by offering something that has been common to other languages like Ruby, Scala and Perl for quite some time

So funny ... the most prominent language known for this stuff is PHP ... and missing :D

I never understood why I had to write (count=count, apples=apples, name=name) when a logical default would suffice.
Just because simply one way isn't enough.