Hacker News new | past | comments | ask | show | jobs | submit login

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.


There's a fantastic "more explicit" version of it: str.format. This really is just an implicit version of str.format(). I just don't understand why such a significant syntax change would make it into python when it deviates so much from their usual mantra.


Guido is not a purity robot, and has been looking for a way to have this feature since perl and python were duking it out in the early nineties. Practicality beats purity.

It isn't a large syntax change, string prefixes have existed since the beginning.


Yes. "Practicality beats purity". This part of the zen of Python, too many people forget about it.

People forget that Python is also about readability, and ease of code exploration is the shell. Fstring is a feature to make that even better.


It is explicit, in that one must use the f'' prefix. There are no syntax changes as u'', b'', and r'' already exist. Positionals make bugs more likely.


It is implicit in that the interpolated values are specified anywhere in scope, not inline as with every other formatting option.

I consider specifying the values or variables alongside the formatting string a requirement to be considered explicit, but I can see how it's a matter of opinion.


    @decorator
    def decorated
Is doing:

    decorated = decorator(decorated)
The switch is implicit too. It's syntaxic sugar to gain a pratical and elegant syntax for a common use case.

It's not going to introduce vulnerability. It's going to make your code easier to write and read. It's going to make bug easier to spot in formating. It's going to make shell sessions easier.


The manipulation (@dec) is still right next to the thing being manipulated (def dec).

I'm not trying to be pedantic. It really does affect readability when syntactic sugar's affect spans an entire scope. Whether or not that effect on readability is greater or less than the gain by the syntactic sugar is always a matter of opinion. Obviously my opinion is out of line with Python's core devs.


It is a syntax change as before f"" was a syntax error:

    >>> f"foo"
      File "<stdin>", line 1
        f"foo"
             ^
    SyntaxError: invalid syntax


> ... though similar to adding a function that didn't exist before.

This is not true and exactly the distinction I'm trying to make:

Adding new packages, functions, objects, etc. can all be backported to older versions and alternative implementations. They also require no updates to ASTs, linters, syntax highlighters, static analysis tools etc.

Adding new syntax is backward incompatible (unless it's added as a from __future__ import to new old releases) and requires changes to all tools that parse Python syntax (the interpreter, ASTs, linters, transpilers, etc).


Ok, true, though I would argue that it isn't entirely new syntax but rather a variation of an existing one.

It is a shame that linters will have to add a letter to their grammar also, but I argue that the everyday usability and readability for millions will outweigh this drawback.


I suppose technically true, though similar to adding a function that didn't exist before. The syntax extension part of the feature (adding a letter to the grammar) is minuscule.



Ha, well, I was I wrong. Thanks for the correction.


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)


That's a good thing due to security reasons as arbitrary expressions are allowed. There are plenty of templating solutions available.


Arbitrary string interpolation was proposed, in a way sure to result in security problems:

"PEP 498 proposes new syntactic support for string interpolation that is transparent to the compiler, allow name references from the interpolation operation full access to containing namespaces (as with any other expression), rather than being limited to explicit name references. These are referred to in the PEP as "f-strings" (a mnemonic for "formatted strings")."

"Full access to containing namespaces?" From strings? Bad, bad idea. This is currently marked as "deferred", but should be marked "rejected with extreme prejudice".


FUD: applies to literals only. There is nothing that could happen in the string that couldn't happen in your code already. No new security concerns.


Example given:

    myquery = sql(i"SELECT {column} FROM {table};")
What could possibly go wrong?


How is that any different from any other string formatting mechanism?

  myquery = sql("SELECT %s FROM %s" % (column, table))


plenty of things can go wrong, since you have control of how many and which variables to interpolate, e.g:

    i"SELECT {settings.SECRET_KEY};"
PS: (I don't know why but HN is not updating the page with the reply links needed, so I'll just edit this)

Yes, I agree. I think that the misunderstanding happened when mixmastamyk wrote

> That's a good thing due to security reasons as arbitrary expressions are allowed. There are plenty of templating solutions available

The point is that even if you don't allow arbitrary expressions (which imho are a mistake, and of which I haven't seen a single use case yet), having this kind of interpolation from strings that are not literals (i.e. are not in the trusted source code) would still be a security issue

Since the PEPs apparently don't propose to extend this to non-literals, we're safe. But it's better to be wary and attentively review such proposals...

In fact, I just realized right now that Animats might have misunderstood PEP 501, since

    sql(i"SELECT {column} FROM {table};")
should be perfectly safe from sqli vulns

PPS: Unless Animats is pointing out how switching i'' for f'' is a terribly simple mistake to do and hard to spot during a code review... I agree with that


But again, if you can inject that into the source code, why can't you just do

  "SELECT {};".format(settings.SECRET_KEY)
Remember that the interpolation only works for string literals, you can't inject that from external input.


I agree. I was pointing out that the f'{a} {b}' syntax can't accomplish everything. Since it isn't intended as a complete replacement, the way `.format` is intended as a complete replacement for `%`, it will just add another string formatting technique without ever deprecating the old way.


Nothing wrong with this, because it's explicit. You could't be mo terse in this case, could you?


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.


Correct, don't use it with i18n, the same as with any other string formatting.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: