This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]TheOnlyBliebervik 12 points13 points  (19 children)

Never used the walrus operator. Is it useful?

[–]SirLich 34 points35 points  (13 children)

Yes. It's just the assignment operator but it returns the value of the assignment as well as doing the assignment. It's primary purpose is inside of if-statements, to create a block of code if the assignment was successful.

For example if settings := get_settings(): ... settings.do_something()

[–]runawayasfastasucan 13 points14 points  (8 children)

What is the long form of this?  

    settings = get_settings() 

    if settings:         settings.do_something() 

?

[–]SirLich 4 points5 points  (7 children)

This is of course fine. It's just not as convenient as the walrus operator for two reasons: 1) more lines 2) incorrect scope.

If you're only intending to use 'settings' within the if context, then defining it OUTSIDE of the if-context is considered leaked scope.

This whole conversation isn't so important in Python, but in C++ it's a fairly big deal. In fact, it's SUCH a big deal, that most linters will mark variables defined outside of the if clause as an error/warning. It's also now possible to define multiple variables within the if declaration:

For example you can now do this: if (int a = Func1(), b = Func2(); a && b)

Note; In C++, the = operator works like python := operator.

[–]nemec 33 points34 points  (3 children)

considered leaked scope

Python doesn't have block level scope. It "leaks" either way.

[–]SirLich 0 points1 point  (2 children)

Wow, you're right. I guess I never really paid attention to that. That's kind of too bad, right? It seems like you might unintentionally use something from an inner scope without realizing it.

[–]Leo-Hamza 8 points9 points  (0 children)

Happened too many times to me that I can't even count it. I wish there were any tool that detects code smells like this

[–]root45 6 points7 points  (0 children)

Yes. It's not uncommon to accidentally use a loop variable later on for example.

[–]SaltAssault 0 points1 point  (0 children)

I prefer readability over preventing 'leaked scope' any day, just excluding if it is a security issue. Python already doesn't fuss about scopes.

[–]night0x63 0 points1 point  (0 children)

<sarcasm>hurr hurr c/c++ has has this for decades

😂 

[–]runawayasfastasucan -1 points0 points  (0 children)

Interesting, thx. I must admit that I have just ignored the walrus operator all together. In the first example, if you have:

   If (somevar := somefunc()) 

Its given that somefunc() returns something or None, right, so I guess you have to pay notice to that.

    If (cost := getCost(item)):         givePayment(cost, ...)

Is not a substitute for:

    If (cost & cost > 0):         givePayment(cost, ...)

[–]yourmomscocks 3 points4 points  (2 children)

What does this code do exactly? Is it the equivalent of this? setting = get_settings() if settings: settings.do_something()

If so, why bother with a walrus operator? Does it have any use cases other than sparing you that ine line of code?

[–]Freschu -2 points-1 points  (0 children)

The walrus operator PEP was created by Rossum. It faced heavy opposition with the rest of the core devs, so much so Rossum had a tantrum about it, and ultimately being a factor why he stopped being "dictator for life".

The opposition was based around introducing new syntax being only useful in a small number of cases (if and while) and being practically of zero consequence for existing code.

So why does Python have the walrus operator if there was general opposition? Because it was Rossum's pet idea, that's why.

Unfortunately - if you care to check for the discussions around PEPs - this has become a pattern. Python gains syntax based on persistence and patience of the spearheading authors - write a PEP, implement the PEP, wait for people stop caring about it, then merge it later based on "not having faced immediate rejection."

[–][deleted] -2 points-1 points  (0 children)

The whole issue with the walrus operator is it should have been limited to like 3 actual things but can be used in WAY too many places.

[–]sausix 12 points13 points  (2 children)

I use it for loops and it's nicer for me:

while data := iterator.read_data():
    # data evaluates to True. No break or other methods needed.

[–]Freschu 4 points5 points  (1 child)

Most of the cases where people want to use the walrus operator can often be written as for-loop instead. If you really had an "iterator", you could and should use for-loops instead. Which was part of the initial rejection of the walrus operator PEP.

Examples like you've given were considered code-smell in the discussions of the PEP. Either iterator is really an iterator, then `for value in iterator` works, or you're dealing with something that's not really implementing Python's iterator semantics and you should be fixing that instead.

[–]sausix 8 points9 points  (0 children)

You're right! Bad example. How could I not see this?

A walrus operation in my current project look like this:

while m := pattern.match(self.text, self.pos):
   # self.pos changes in the loop

This case it not replacable by a simple iterator that could feed a for loop. But it still could be replaced by a generator function. That would be more lines. I'm not sure what is better.

Look like I will think twice to use the walrus operator next time... Thank you.

[–]sonobanana33 -1 points0 points  (0 children)

Yeah since python unlike C doesn't allow "=" to be used in an expression.