On Thu, Oct 22, 2020 at 8:22 PM Steven D'Aprano
On Wed, Oct 21, 2020 at 07:17:21PM -0700, Guido van Rossum wrote:
Hmm, if the above is acceptable, maybe f-strings are still the logical next step, since they bring the format and the target name together again.
That's not the only way to bring the format and target name together. Both brace-style and percent-style can do that:
'{number:d}' '%(number)d'
Maybe, but if it isn't an actual syntactic construct, there's no value - at best, all you can do is return a dictionary, and there's no convenient way to assign those to locals.
f-strings also bring so much more to the table than is needed. For this syntax to be sensible, we would have to prohibit so many legal f-strings that it seems perverse to continue calling the subset of what's left over f-strings.
1. They don't behave like f-strings: text scanning, not evaluation of code. What meaning could we give an f-string target like this?
f'{len(x)+1}' = string
...... mini-language inspired by format language. I'm really not sure how many times this has to be said. You don't see C programmers complaining that sscanf and sprintf don't support the exact same set of things. They're sufficiently similar that it is incredibly practical and useful; I think there might be something in the zen of Python about that...
4. Actual f-strings need the prefix to distinguish them from regular strings. But as an assignment target, there is no existing meaning to
'email: {name}@{domain}' = string
so the f prefix has no purpose.
When they have so little in common with f-strings, apart from a spurious and unnecessary f-prefix, why are we calling them f-strings?
If you're saying that this would be best done with an "assign to string literal" syntax, then maybe, but I think the similarity with RHS f-strings is useful enough to keep the prefix. Additionally, the fact that both of them have to be syntactic constructs rather than reusable objects is a useful parallel and a useful reminder.
Another problem is that using only a literal/display form as a target means you can't pre-assemble a pattern and apply it later:
# Match only the given domain. domain = get_wanted_domain() pattern = 'email: {name}@%s' % domain # ... now what?
Right, and you can't do that with f-strings on the RHS either. The specific thing you're asking about could easily be implemented as a feature of the minilanguage itself, but I'm not sure it'd actually be needed. Building patterns for future parsing is simply not the job of this feature - use a regex if you need that.
I guess you could fall back to eval:
eval('f{!r} = {!r}'.format(pattern, string))
but given that both the pattern and the string to be scanned are likely to contain untrusted strings, that's probably not a good idea.
Agreed. Don't do that. There are PLENTY of better options than eval. ChrisA