Why can't Python's walrus operator be used to set instance attributes?

无人久伴 提交于 2020-12-29 11:45:48

问题


I just learned that the new walrus operator (:=) can't be used to set instance attributes, it's supposedly invalid syntax (raises a SyntaxError).

Why is this? (And can you provide a link to official docs mentioning this?)

I looked through PEP 572, and couldn't find if/where this is documented.


Research

This answer mentions this limitation without an explanation or source:

you can't use the walrus operator on object attributes


Sample Code

class Foo:
    def __init__(self):
        self.foo: int = 0

    def bar(self, value: int) -> None:
        self.spam(self.foo := value)  # Invalid syntax

    def baz(self, value: int) -> None:
        self.spam(temp := value)
        self.foo = temp

    def spam(self, value: int) -> None:
        """Do something with value."""

Trying to import Foo results in a SyntaxError:

    self.spam(self.foo := value)
              ^
SyntaxError: cannot use assignment expressions with attribute

回答1:


PEP 572 describes the purpose of this (emphasis mine):

This is a proposal for creating a way to assign to variables within an expression using the notation NAME := expr.

self.foo isn't a variable, it's an attribute of an object.

The Syntax and semantics section specifies it further:

NAME is an identifier.

self.foo isn't an identifier, it's two identifiers separated by the . operator.

While we often use variables and attributes similarly, and sometimes will sloppily refer to self.foo as a variable, they aren't the same. Assigning to self.foo is actually just a shorthand for

setattr(self, 'foo', temp)

This is what allows you to define getters and setters for attributes. It would complicate the specification and implementation of the assignment expression if it had to work with attributes that have customized setters.

For instance, if the setter transforms the value that's being assigned, should the value of the assignment expression be the original value or the transformed value?

Variables, on the other hand, cannot be customized. Assigning to a variable always has the same, simple semantics, and it's easy for the expression to evaluate to the value that was assigned.

Similarly, you can't use the walrus operator with slice assignment. This isn't valid:

foo1[2:4] := foo2[1:3]


来源:https://stackoverflow.com/questions/64055314/why-cant-pythons-walrus-operator-be-used-to-set-instance-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!