4 ms·
Ah yes, I've been doing this with stdout.write since Python 2; it didn't occur to me that when Python 3 turned print into a function that would make it usable i
by chriswarbo 3y ago
Ah yes, I've been doing this with stdout.write since Python 2; it didn't occur to me that when Python 3 turned print into a function that would make it usable in lambdas!
You're right that the walrus makes assignment more usable; we can also call methods like .__setitem__ to get similar effects. Unfortunately the walrus seems to suffer the same broken/ambiguous scoping as assignment statements, e.g.
>>> a = 1
>>> b = lambda: (print(a), a := 2)
>>> b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
UnboundLocalError: cannot access local variable 'a' where it is not associated with a value
> Don't need return in a lambda
`return` is needed for early returns. Notice that my `abs` example is trying to do that with `return n` (to skip the `-1 *` operation, since `n` is non-negative in that case).
> Leaves raise and a few other odds and ends
Off the top of my head: yield, match, def, import, class, with, for, while, assert, try, except, async, await.
- mixmastamyk 3y agob = lambda: (a := 2, print(a)) Hmm, need to put the assignment before. Can't access nonlocals unless you only read the the var and don't write to it. That's the way functions in python work as well.
- chriswarbo 3y ago> Hmm, need to put the assignment before. No, that would not have the intended behaviour: your `print(a)` is reading a fresh local variable, defined by the `:=` expression (which shadows that from the outer scope), so it will output '2'. The intended behaviour is to print '1' and reassign the outer name; but we can't do that (that's why I chose it as an example!) > Can't access nonlocals unless you only read the the var and don't write to it. That's the way functions in python work as well. Yes, that is precisely what I meant when I said it "suffers the same broken/ambiguous scoping as assignment statements". Python took a haphazard, WorseIsBetter approach to assignment/declaration/scoping. The resulting behaviour is complex, confusing and involves spooky action-at-a-distance (e.g. the meaning of my `print(a)` expression was altered by the presence of an ':=' expression which hadn't been reached yet!). Since this doesn't really affect simple "top to bottom" scripts, it only became an issue once large applications and frameworks started emerging; by that time it was too late to fix, since there was too much Python code in the wild to justify such a large breaking change :(
- mixmastamyk 3y agoI merely explained why it didn't work, for any passerby. I don't think the rules are hard to understand once described. There's basically only one of consequence—if writing outside the current scope there neeeds to be a clarifying statement first to avoid ambiguity. Unfortunately that prevents usage in a lambda. However, I don't think complex functionality belongs in them either, so not a big loss. See the Beyonce rule mentioned elsewhere in this thread.