Why does using the walrus operator on a member variable raise a SyntaxError?
Asked Answered
H

1

6

Why can't I use the walrus operator := to assign to an attribute? It works when assigning to a local variable:

my_eyes = ["left", "right"]
if saved_eye := my_eyes.index("left"):
    print(saved_eye)

# outputs >>> 0

But it is a syntax error if I try to assign to an object attribute:

class MyEyes:
    def __init__(self):
        self.eyes = ["left", "right"]
        self.saved_eye = None

    def ohyes(self):
        if self.saved_eye := self.eyes.index("left"):
            print(self.saved_eye)

x = MyEyes()
x.ohyes()

# raises 
# >>> if self.saved_eye := self.eyes.index("left"):
# >>> SyntaxError: cannot use assignment expressions with attribute 

I mean I can bypass the error using a temporary local variable but why would this happen? I believe 100% it is a legal syntax.

Hawkeyed answered 26/4, 2021 at 2:38 Comment(0)
T
5

The syntax is illegal, as stated in the PEP 572, where the walrus operator (aka "assignment expression") is defined:

Most importantly, since := is an expression, it can be used in contexts where statements are illegal, including lambda functions and comprehensions.

Conversely, assignment expressions don't support the advanced features found in assignment statements:

Single assignment targets other than a single NAME are not supported:

# No equivalent
a[i] = x
self.rest = []

It's a little bit wordy, but this means that the walrus operator doesn't support assignment for attributes.

The error you are getting is quite specific to the situation too, validating this ("cannot use assignment expressions with attribute" means "cannot use walrus operator setting an attribute").

Tycho answered 26/4, 2021 at 2:52 Comment(1)
In other words, the walrus operator is used to assign to variables within an expression. self.rest isn't a variable, but rather an attribute of the self object. See #64055814 for a bit more discussion.Aleris

© 2022 - 2024 — McMap. All rights reserved.