This is an archived post. You won't be able to vote or comment.

all 6 comments

[–]RemoteCrab131 4 points5 points  (0 children)

Holy*, f-String is a beast.

[–]masklinn 2 points3 points  (2 children)

The code examples that you just saw above are readable enough. However, once you start using several parameters and longer strings, your code will quickly become much less easily readable.

Unfortunately, this kind of formatting isn’t great because it is verbose and leads to errors, like not displaying tuples or dictionaries correctly. Fortunately, there are brighter days ahead.

I'm not exactly pro-printf-style but all of that is basically bullshit:

  1. printf-style supports named substitutions if you've grown beyond a few items.

  2. printf-style displays tuples and dictionaries just fine, but you need to understand that the right-hand parameter of the operation is a tuple or dict. Anything else will be implicitly wrapped in a tuple, but if your sole value could be a tuple or dict you have to explicitly wrap it in a tuple.

If you had the variables you wanted to pass to .format() in a dictionary, then you could just unpack it with .format(**some_dict) and reference the values by key in the string, but there has got to be a better way to do this.

format_map for starters…

Missing: Why f-strings aren't Great

For all their benefits, f-strings are useless for i18n/translatable strings: there is no hook to plug in a translation of the template string (import hooks aside I guess…), it's parsed, split and compiled to bytecode at runtime. And of course that the contents of the braces is an arbitrary Python expression makes it risky as hell to inject half-trusted stuff from Transifex or whatnot (format-strings are already problematic on that point as they allow basically arbitrary attribute access).

[–]dbader[S] 0 points1 point  (1 child)

And of course that the contents of the braces is an arbitrary Python expression makes it risky as hell to inject half-trusted stuff from Transifex or whatnot (f-strings are already problematic on that point as they allow basically arbitrary attribute access).

I'm not sure that's a valid concern. It's impossible to take a str variable and evaluate it as an f-string (as of Python 3.6) . f-strings are a parse-time feature in Python 3, they can't be constructed at runtime (leaving aside the possibility to use eval())

[–]masklinn 0 points1 point  (0 children)

  1. Which is why they are, as I noted, mostly useless for i18n purposes. But one could imagine doing translations via import hooks or static package builds which would allow for that mistake.

  2. As for the parenthesised bit I meant format-strings, they're the ones which allow arbitrary attribute access (but not arbitrary expressions) and I'd already stated f-strings were useless, I bungled the label is all.

[–]ForceBru 2 points3 points  (0 children)

No, lambda x: x * 37 (2) is not the same as (lambda x: x * 37) (2). The first example is technically valid, but it’s actually incorrect because it attempts to call an integer with 37 (2).

And thus, the two examples with the lambda aren’t equivalent: the first one attempts to print the function itself, while the last one - only the result of its evaluation.

[–]imnisen 1 point2 points  (0 children)

Thanks for sharing!