On 2020-09-17 12:16, Alex Hall wrote:
On Thu, Sep 17, 2020 at 8:57 PM Brendan Barnwell <brenb...@brenbarn.net
<mailto:brenb...@brenbarn.net>> wrote:
On 2020-09-16 21:52, Dennis Sweeney wrote:
> TL;DR: I propose the following behavior:
>
> >>> s = "She turned me into a newt."
> >>> f"She turned me into a {animal}." = s
> >>> animal
> 'newt'
>
> >>> f"A {animal}?" = s
> Traceback (most recent call last):
> File "<pyshell#2>", line 1, in <module>
> f"A {animal}?" = s
> ValueError: f-string assignment target does not match 'She
turned me into a newt.'
>
> >>> f"{hh:d}:{mm:d}:{ss:d}" = "11:59:59"
> >>> hh, mm, ss
> (11, 59, 59)
I don't like this at all. It looks like assigning to a
literal, which
is weird.
People keep saying this, but iterable unpacking looks like assigning to
a literal (a tuple or list literal) just as much.
Only if you keep using extremely simple template strings that don't
contain anything except the variables you're assigning to. But this
proposal allows the string to contain ANYTHING. The assignment targets
may represent only a small part of it. For tuples and lists of
assignment targets, the target list/tuple can't contain any extraneous
material apart from the variables you're assigning to. There is no
assign-to-a-tuple analogue of
f"My name is {name} and I am {age} years old" = "My name is Bob and I am
100 years old"
Also PEP 622 proposes something that looks like assignment to a function
call, albeit within a match/case statement.
That doesn't look like an assignment, because there's no equals sign.
In any case, I'm not sure I support PEP 622 as it stands either, for
similar reasons to why I don't support this current proposal.
It's natural to have symmetry between assignments and expression. For
another example, look at subscripting, i.e. `__getitem__` vs `__setitem__`.
Also, it hides the assignment target within a string of
potentially unbounded length and complexity, which makes it
difficult to
reason about code because it's hard to see when variables are being
assigned to.
It's really not. A decent IDE should already be able to automatically
show you assignments and usages of a variable - PyCharm does with one
Ctrl+click. A syntax highlighter that can handle f-strings will make the
assignments obvious at a glance.
No, it won't, unless the target string is simple. Also, the assigned
values won't be easily discernible in the right-hand string, because
there are no delimiters there to mark them.
In any case, even if it were borderline possible with an IDE, it's
still not useful or important enough to me to gum up an operation as
basic as assignment. I'm fine with putting it into a function call or
something like that, but not overloading the assignment statement in
this way.
It also introduces a whole host of questions about the
details of the parsing (i.e., how does the greediness work if the
pattern is something like "{one} {two} {three} {four}" and the
string to
be parsed is five or ten words).
This I agree with, another reason to go for putting regexes in the
f-strings like I suggested.
I think a better approach for something like this would be
a .parse()
method of some sort on strings, sort of like the inverse of .format().
It would parse a given string according to the format string and return
a dict with the mappings (just as format can take a dict in and return
the string with the substitutions made). So it would be like:
>>> pattern = "That {animal} is really {attribute}."
>>> d = pattern.parse("That snake is really powerful.")
>>> d['animal']
'snake'
>>> d['attribute']
'powerful'
I think someone else just made the same proposal. But how does this
solve the greediness issue?
It doesn't, but that's the least important of my objections. What it
does solve is it avoids adding new behavior to the assignment statement,
and it avoids creating a way to inject local variables whose names
and/or values are unclear in the statement where they're created.
This wouldn't let you assign the results into local
variables, but I
think that's a good thing. Creating local variables "programmatically"
is not a good idea; it's better to use a dict.
How is
f"{a} {b}" = "1 2"
creating local variables any more "programmatically" than
a, b = "1 2".split()
? The variables are static and visible to the compiler.
As I mentioned above, your examples are unrealistically simple. If you
know your string is like "1 2" and you want to assign to a, b, you do
what you just showed: use split. But in the "Bob is 100 years old"
example I gave, it is more programmatic, because there is matching going
on which is extracting parts of the RHS string, and you have to
carefully read both the LHS and the RHS to see which parts are extracted
into which variable. And that is still a pretty simple example, with
relatively short and unambiguous strings on both sides of the equals
sign. As the string grows longer and more complicated, it only becomes
more programmatic.
I think we may be arguing from different premises here, though, because
I think the real issue is that for me the equals sign and local variable
names are quite sacred objects. I'm not sure I would even support
nested tuple and list assignments if they didn't exist and were proposed
today. All of these forms of assignment that are being discussed are
too complicated to put into the simple assignment statement to be used
to create local variables. It's fine to have the parsing side of it
going on, but there just isn't any reason, in my view, to have it be
part of an assignment statement that creates local variables. Just have
it be a function call that creates a dict.
--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no
path, and leave a trail."
--author unknown
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/OMFJXQLENIEFHHN45UYJH7OGTJG55R4F/
Code of Conduct: http://python.org/psf/codeofconduct/