为什么不能使用 Python 的 walrus 运算符来设置实例属性? [英] Why can't Python's walrus operator be used to set instance attributes?

查看:64
本文介绍了为什么不能使用 Python 的 walrus 运算符来设置实例属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚了解到新的 walrus 运算符 (:=) 不能用于设置实例属性,它应该是无效的语法(引发 SyntaxError).

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?)

我查看了 PEP 572,但找不到是否/在哪里记录.

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

研究

这个答案提到了这个限制,没有解释或来源:

This answer mentions this limitation without an explanation or source:

不能在对象属性上使用 walrus 运算符

you can't use the walrus operator on object attributes


示例代码

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."""

尝试导入 Foo 导致 SyntaxError:

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

推荐答案

PEP 572 描述了这个目的(强调我的):

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

这是创建一种使用符号NAME := expr 在表达式中为变量赋值的方法.

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

self.foo 不是变量,而是对象的属性.

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

语法和语义 部分指定了它进一步:

The Syntax and semantics section specifies it further:

NAME 是一个标识符.

self.foo 不是标识符,它是由 . 运算符分隔的两个标识符.

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

虽然我们经常类似地使用变量和属性,有时会草率地将self.foo称为变量,但它们并不相同.赋值给 self.foo 实际上只是

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)

这允许您为属性定义 getter 和 setter.如果必须使用具有自定义 setter 的属性,则会使赋值表达式的规范和实现复杂化.

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.

例如,如果 setter 转换了被赋值的值,赋值表达式的值应该是原始值还是转换后的值?

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.

同样,不能将 walrus 运算符与切片赋值一起使用.这无效:

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

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

这篇关于为什么不能使用 Python 的 walrus 运算符来设置实例属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆