The author's expectations seem strange. Take another example:
a = b = random.random()
I would not expect a and b to get different values. It would be very strange if using `[]` had different behavior than a function call in the same place. Am I out of step here?
What expectations? The author states right up front "I've known of this behavior for a long time".
A somewhat trickier example of the same issue is using [] as a default parameter value ... though there are warnings about the problem with that (it's the same list on every call) throughout the documentation.
I've seen stuff posted about chained assignment footguns in python regularly over the years, and it always surprises me. I don't think I've ever written them, or reviewed code that does. I don't think it'd occur to me to even think about writing a chained assignment.
Is chained assignment a pattern that comes from another language that people are applying to python?
“Since Python 3.6, every Python instruction has been given an odd number of arguments (even if it doesn't need any) so that the byte offsets are always even.”
I don’t think this is true. I think something like it is true for CPython (an argument isn’t added but the byte is kept for functions w no arg) but it’s not a statement about Python.
Chained assignments are banned according to the style guide at my workplace. Too many opportunities for misuse. And if you insist on a one-liner assignment to two variables just use two statements separated by the semicolon. I challenge anyone to work out what this code does:
> I challenge anyone to work out what this code does
It's unusual, but pretty obvious. In single steps it's basically this:
a, b = 1, [0, 1, 2, 3]
b[a] = b
which would be b[1]=b because a==1. So this creates a self referencing list. The deeper reason here is, everything is a pointer to data in memory, even if in source code we see the actual data. That's why b[1] is storing the pointer to the list, not the data of the list.
If someone is doing BS like this, they deserve spanking. But banning the whole concept because people are unaware or how something is to be used properly is strange. But then again, it seems people have a bit of a problem how python really works and how it's different from other languages.
> list object is constructed once and assigned to both variables
Ummm no the list is constructed once and assigned to b and then b is assigned to a. It would be crazy semantics if `a = b = ...` meant `a` was assigned `...`.
Edit: I'm wrong it's left to right not right to left, which makes the complaint in the article even dumber.
jp57|12 days ago
maxnoe|12 days ago
The initial line is the same, but:
Only because floats are immutable and thus an implicit copy is made and lists are mutable so the same mutable instance is pointed to by both names.This talk still applies despite its age: https://youtu.be/_AEJHKGk9ns?si=q5HjMOM9QS3_bFzH
jibal|12 days ago
A somewhat trickier example of the same issue is using [] as a default parameter value ... though there are warnings about the problem with that (it's the same list on every call) throughout the documentation.
KerrickStaley|12 days ago
Twirrim|12 days ago
Is chained assignment a pattern that comes from another language that people are applying to python?
selridge|12 days ago
I don’t think this is true. I think something like it is true for CPython (an argument isn’t added but the byte is kept for functions w no arg) but it’s not a statement about Python.
kccqzy|12 days ago
PurpleRamen|12 days ago
It's unusual, but pretty obvious. In single steps it's basically this:
which would be b[1]=b because a==1. So this creates a self referencing list. The deeper reason here is, everything is a pointer to data in memory, even if in source code we see the actual data. That's why b[1] is storing the pointer to the list, not the data of the list.If someone is doing BS like this, they deserve spanking. But banning the whole concept because people are unaware or how something is to be used properly is strange. But then again, it seems people have a bit of a problem how python really works and how it's different from other languages.
mathisfun123|12 days ago
Ummm no the list is constructed once and assigned to b and then b is assigned to a. It would be crazy semantics if `a = b = ...` meant `a` was assigned `...`.
Edit: I'm wrong it's left to right not right to left, which makes the complaint in the article even dumber.
kccqzy|12 days ago
> An assignment statement evaluates the expression list and assigns the single resulting object to each of the target lists, from left to right.
Consider this:
If assignment were to happen right to left, you would get a NameError exception because the first assignment would require an unbound variable.ayhanfuat|12 days ago
Wouldn't that require a LOAD_FAST? Also a is assigned first (from left to right) so a = ... happens either way.