【发布时间】:2021-03-08 09:14:30
【问题描述】:
赋值给表达式(相对于名称)在 Python 中很常见。例如,这是完全有效的语法:
my.object["with_some"].very_long["expression"] = func(my.object["with_some"].very_long["expression"], my.object["with_some"].very_long["expression"])
但是,如果我尝试使用海象运算符通过将 LHS 设为命名表达式来缩短它,例如
(x:=my.object["with_some"].very_long["expression"]) = func(x, x)
Python 引发 SyntaxError:
语法错误:无法分配给命名表达式
同样,for x[0] in range(5) 是有效的语法(只是非常混乱),而 for (a:=x[0]) in range(5) 又是 SyntaxError: cannot assign to named expression。
为什么我不能分配给命名表达式?这是设计使然还是实现?
PEP 572 提到了一些无法使用海象运算符的情况,但除了一种情况外,所有情况都与无括号表达式的语法有关,最后一种情况与 f 字符串有关。与this answer ((self.x := ...)) 中指出的情况不同,在我的例子中,海象运算符中的赋值目标是一个简单的名称/标识符,而不是表达式。 the language reference 也不清楚为什么不允许这样做。 Googling the error message 今天在撰写本文时恰好产生了三个结果:一个 issue about limitations in comprehensions、一个 Stack Overflow chat message expecting hundreds of Hot Network Questions(没有发生)和 an issue in a 3rd-party Python parser;没人帮我。
我无法分配给命名表达式的原因是什么?这是在某处记录或定义的设计规则,还是实施限制?据我所知,它不会导致任何歧义,而且我的用例似乎应该是有效的。
【问题讨论】:
-
你可以这样做:
f(x:=..., x)。但这并不能回答“为什么我不能分配给命名表达式?”你问题的一部分。 -
@hiroprotagonist 是的,我可以,但我仍然需要在赋值运算符的左侧和右侧重复长表达式(在右侧只需一次而不是两次)。
-
命名表达式的值是表达式的值。值不是您可以分配的东西。你认为
(x := a+b) = f(x)是什么意思? -
@Barmer 我希望
(x := a+b) = c会因cannot assign to operator而失败,就像a+b = c没有命名表达式一样。同样,for x[0] in range(5)是有效语法,for (a:=x[0]) in range(5)是SyntaxError: cannot assign to named expression。 -
@gerrit,请看我的扩展答案。
标签: python syntax-error python-3.8 walrus-operator