5 ms·
You can pry the walrus operator from my cold dead hands. m = re.match(pattern1, line) if m: do_stuff(m.group(1)) else: m = re.match
by sfink 1y ago
You can pry the walrus operator from my cold dead hands.
m = re.match(pattern1, line)
if m:
do_stuff(m.group(1))
else:
m = re.match(pattern2, line)
if m:
do_other_stuff(m.group(2))
else:
m = re.match(pattern3, line)
if m:
do_things(m.groups())
else:
m = ...
Obviously, there are ways to improve this particular example without using the walrus. But it's also usually not this simple.
I run into something like this all the time. Not many times per program, and I don't actually use the walrus all that often, but when it's the right thing it's so very nice.
- marcosdumay 1y agoYou know, creating functions is allowed in Python. As are loops. The assignment is the least problematic thing on that code. I do even disagree on it being a problem.
- callc 1y agoEven though I’ve never used python walrus, I’m a huge fan of the “X language feature can be used as an expression” I feel the same way with rust control flow being used as an expression, and am disappointed when other languages don’t have it. Even though one could argue it makes things more complicated, I feel more mental freedom and feel the language getting out of the way.
- pansa2 1y agoThe walrus operator hardly changes that example at all: if m := re.match(pattern1, line): do_stuff(m.group(1)) else: if m := re.match(pattern2, line): do_other_stuff(m.group(2)) else: if m := re.match(pattern3, line): do_things(m.groups()) else: m = ... I've found `:=` useful in the headers of `while` loops, but that's about it. The complexity that walrus adds to the language far outweighs its usefulness.
- ghewgill 1y agoThe walrus operator allows you to use `elif` there to avoid cascading indentation. if m := re.match(pattern1, line): do_stuff(m.group(1)) elif m := re.match(pattern2, line): do_other_stuff(m.group(2)) elif m := re.match(pattern3, line): do_things(m.groups()) else: ...
- pansa2 1y agoAh, I missed that. Thanks
- sfink 1y ago...and for me, the benefit is that this is much more clear to me when reading the code. An increasing level of indentation directly maps to needing to keep more in my head. (Sure, in this case you can pattern match and see that there's nothing else, but in general you need to watch out for cases where the else may be doing more than just the next check on the same inputs. ) But the walrus is good even in the absence of a series of matches. It is quite common to need to know more than the boolean "did this match or not?", and so to my eye it is much cleaner to have one line doing the test and the next lines using the results. I don't care about saving characters or even lines. `m = ...match...` immediately followed by `if m:` feels like overhead for the sake of the programming language's limitations; it's extraneous to what I want to express. Also, I assert that the pattern is better for correctness. It's like Rust's `if let Some(foo) = f() { ... }` pattern: guard on a certain condition, then use the results if that condition is true. v = f() if v: ...use v... invites injecting code in between the assignment and the test. They're two different things to the reader. And it's not as clear that `v` should only be used in the consequent body. if v := f(): ...use v... says exactly what it means: `f()` may return a truthy value. If it does, do something with it.
- Veedrac 1y agoFWIW another way to handle this is a local function with early returns. In this example you can also just use a single regex and most likely win performance too. := is so common in other languages, or even other Python statements, that it doesn't bother me at all, but Python is such an imperative-first language that its presence is rarely felt.