7 ms·
I can't say I like the f" syntax much. I think JS's backtick is better. Other than that, I agree, much better than % and less verbose than .format. It's just
by noncoml 6y ago
I can't say I like the f" syntax much. I think JS's backtick is better.
Other than that, I agree, much better than % and less verbose than .format.
It's just the f" or f' that doesn't sit right with me
- dharmab 6y agoIt's consistent with other strings in Python like r-strings and the older u-strings.
- teddyh 6y agoAnd b-strings.
- nurpax 6y agoYup, especially as you often need to access dict's with foo["field"] and you get a syntax error if the f-strings is also f"". JavaScript backtick syntax doesn't lead to this extra syntactic friction.
- quietbritishjim 6y agoYou can use any of f"{foo['field']}" f'{foo["field"]}' f"""{foo["field"]}""" (I see from your carefully worded first sentence that you already knew this but still find it annoying, but I'll leave this here for any that aren't aware.)
- mixmastamyk 6y agoYes, and anyone who has written a "one-liner" at the command line is familiar with it. Wouldn't say it is a big problem.
- psalminen 6y agoThe problem with this is when you run it through a formatter that changes all ' to ".
- dmurray 6y agoSounds like a bug in your formatter, if it's meant to just do formatting but actually replaces valid syntax with invalid.
- psalminen 6y agoI don't totally disagree. My company uses the black formatter, which does this[0]. There are flags to skip string formatting, but is frowned upon at my organization. [0] https://github.com/psf/black/blob/master/docs/the_black_code_style.md#strings https://github.com/psf/black/blob/master/docs/the_black_code...
- nimih 6y agoFor what it's worth, black appears to do a reasonable thing and preserves the semantics of your quoted strings (as is promised by the documentation): $ echo "'foo'" | black - "foo" $ echo "'foo[\"bar\"]'" | black - 'foo["bar"]' $ echo "'foo[\"bar\"]+\\'baz\\''" | black - "foo[\"bar\"]+'baz'"
- wskinner 6y agoThis is easily avoidable in python by using single quotes for the outer string and double quotes for the inner string, or vice versa. Or, use triple quotes for the outer string.
- dragonwriter 6y agoYeah, if you get to the level of nesting where having available quotes is an issue, you really need to break it up into multiple expressions.
- ziml77 6y agoI'm surprised it works like that in Python. C# has similar interpolated strings but there it's legal to embed quotation marks within the curly brackets. Though I guess it's less necessary in Python since you can just use the other type of quote inside.
- ericvsmith 6y agoThis is because of how f-strings were initially implemented: I piggy-backed them off of "regular" strings, then post-parsed inside that string. But the restriction is that the entire f-string (after the f) needs to be a valid regular Python string. Since this: "this is a "regular" string" isn't valid, then neither is this: f"dict lookup: {d["key"]}" However, we've talked about changing f-string parsing from a "post-process regular strings" mode, to instead having the tokenizer and parser themselves aware of f-strings. When we do that, the f-string example above will work. (edit for formatting)
- foob 6y agoIt can feel annoying sometimes, but it's also nice that it prevents you from getting overly complicated with your string interpolations. Human readability is highly valued in Python culture, and things start getting hard for humans to quickly parse when you allow arbitrarily complex interpolation expressions. Assigning your complicated expression to a well-named variable first will usually make your code more readable, even if it's slightly more verbose.
- mixmastamyk 6y agoI agree it's not the most beautiful, but it was the best choice given the requirements. Basically, it had to be explicit, concise, use unused ASCII syntax, and not be too cryptic or incompatible. Other quote types or backticks were not available or an option. (I spent a lot of time thinking about it, and put the idea forward on python-ideas. Though string interpolation is nothing new of course.)
- patrec 6y agoI think you are right to prefer JS's backtick notation, but not in your reason. The main problem with python's f" syntax is that it's just a very complex, non-extensible hack whereas in javascript you can prefix a tag to specify how the interpolation happens. Instead of this, f-strings have a lot of hardcoded and often broken behavior which can't be fixed let alone customized. For example, you can specify a field width, but it will not even work properly even in a fixed-width context, because of quite common things like emojis or CJK or combining characters don't have their width computed correctly.
- mixmastamyk 6y agoIt's not a hack or broken. The formatting language existed before f-strings and is somewhat a separate issue. I'm not sure I expect it to handle every Unicode nuance either, when there are modules in the stdlib for that.
- earthboundkid 6y agoYes. Python in general has gone from being “executable pseudo code” to a series of complex language design trade offs largely because it had failed to grasp the right abstractions in its evolution. Backtick functions in JS are so powerfully clever and basically impossible to recreate in Python.
- pansa2 6y ago> Python in general has gone from being “executable pseudo code” to a series of complex language design trade offs Agree with this 100%. > because it had failed to grasp the right abstractions in its evolution. I'd be interested to know what you think the language's designers should have done differently?
- earthboundkid 6y agoLet’s go all the way back to `with`. What does it do? It encapsulates try/finally blocks and only try/finally. That is a weirdly specific thing to encapsulate. Why did they do that? Well, it turns out that making an anonymous block syntax that is compatible with Python’s grammar is hard, so you can’t have the equivalent of this JavaScript: WithOpen(filename, f => { // block }) Because blocks aren’t viable, problems have to be solved on a case-by-case basis, which is hard to do well and leaves gaps.
- ericvsmith 6y agoI've put together a proposal to have all strings be f-strings by default. Then you could drop the "f" prefix. I also propose adding a "p" prefix (for "plain") to remove the f-string parsing behavior. I talked about it at the last Python core sprint, and it only got lukewarm support, so I'm not sure I'm going to pursue it.
- cdrini 6y agoI would personally be quite against that. That's a pretty large breaking change, with no clear benefit. It doesn't make the feature more discoverable, since you still need to know that using "{}" will cause interpolation. I'd say net zero effect on readability; mostly just individual preference. And potential negative impact on performance.
- ericvsmith 6y agoThere would be a __future__ import to turn it on, at least for some number of releases. But yeah, I'm not sure it should ever be the default behavior. It makes most sense to me as a per-module opt-in, but then a __future__ import doesn't make sense. And we've resisted having per-module pragmas, so maybe it's dead in the water.
- boothby 6y ago> And we've resisted having per-module pragmas, so maybe it's dead in the water. There's a hack for that (no apologies for the self promotion; the project is a just funnin') https://github.com/boothby/dissert https://github.com/boothby/dissert
- Blikkentrekker 6y agoCertainly this will lead to rather confused programmers. F-strings certainly seem like opt-in behavior to me.
- dragonwriter 6y ago> I've put together a proposal to have all strings be f-strings by default. Please, no. I mean, it would be a breaking change, which needs a really compelling case, will make all introductory material wrong, and...offers what benefit?
- pansa2 6y agoI quite like the idea of using double-quotes for format strings and single-quotes for normal strings. This isn’t sufficient on its own, though - what about raw strings? Perhaps use “” for format strings, ‘’ for raw strings and get rid of normal strings altogether?