分配给表达式(相对于名称)在Python中很常见。例如,这是非常有效的语法:
my.object["with_some"].very_long["expression"] = func(my.object["with_some"].very_long["expression"], my.object["with_some"].very_long["expression"])但是,如果我试图使用walrus运算符来缩短它,我会让LHS成为一个命名表达式,例如
(x:=my.object["with_some"].very_long["expression"]) = func(x, x)Python引发一个SyntaxError:
SyntaxError:不能分配给命名表达式
类似地,for x[0] in range(5)是有效的语法(只是非常混乱),而for (a:=x[0]) in range(5)又是一个SyntaxError: cannot assign to named expression。
为什么我不能分配给一个命名的表达式?这是通过设计还是通过实现?
佩普572提到了不能使用walrus运算符的一些情况,但除了一种情况外,其余都是关于无括号表达式的语法,最后一种是关于f-字符串的。与这个答案 ((self.x := ...))中指出的情况不同,在我的示例中,walrus运算符中的赋值目标是一个简单的名称/标识符,而不是表达式。语言参考也不清楚为什么不允许这样做。在编写本报告时,搜索错误信息产生了三个结果:一个关于理解限制的问题,一个堆栈溢出聊天消息等待数百个热门网络问题 (没有发生)和第三方Python解析器中的一个问题;没有人帮助我。
我不能分配给命名表达式的原因是什么?这是一个在某个地方被记录或定义的设计规则,还是一个实现限制?据我所见,它不会导致任何歧义,而且我的用例应该是有效的。
发布于 2020-11-25 14:31:32
my.object["with_some"].very_long["expression"] = \
func(my.object["with_some"].very_long["expression"],
my.object["with_some"].very_long["expression"])`是句法上的糖
my.object["with_some"].very_long.__setitem__(
"expression",
func(my.object["with_some"].very_long["expression"],
my.object["with_some"].very_long["expression"]))所以它不像你想的那样对称。原始长表达式的值(而不是表达式本身)作为两个参数传递给func,而原始表达式本身只是赋值的目标。
但是,你可以写
x["expression"] = func(
(x:=my.object["with_some"].very_long)["expression"],
x["expression"])在将x分配给desugared版本的一个公共表达式的值时,my.object["with_some"].very_long。
赋值表达式必须位于赋值的右侧,因为这是在左侧之前计算的。而且,它必须是使用:=的第一个参数,因为函数参数保证从左到右计算。
假设我适当地定义了A,下面是我用来验证上面是否应该工作的测试。
class A:
def __init__(self, y):
self.b = dict(foo=y)
def func(x, y):
return x + y
a = A(A("bar"))
x["foo"] = func((x:=a.b["foo"].b)["foo"], x["foo"])a.b["foo"].b["foo"]的新值是"barbar",这与func的定义所期望的一样。
发布于 2020-11-25 13:56:39
海象运算符只将其赋值为副作用-它的值不是左手边变量,而是其右手边表达式的结果。
所以命名表达式的值
(x:=my.object["with_some"].very_long["expression"])是海象运算符(:=)右侧的结果,即表达式的结果。
my.object["with_some"].very_long["expression"]让我们表示为result,所以您的命令
(x:=my.object["with_some"].very_long["expression"]) = func(x, x)是相同的
result = func(x, x)现在,result是一个值,而不是变量名。也许是None,也许是一个数字,可能是一个特定的列表或者其他什么东西,但是在赋值运算符的左边是不允许的。
因此,分配给命名表达式(至少在大多数情况下)是没有意义的,因此不允许。
发布于 2020-11-25 14:58:46
比较:
my.object["with_some"].very_long["expression"] = func(7, 7) # OK使用
7 = func(7, 7) # error解释如下:
(=)的左边不是对象的属性,而是它的值。
7=职能c(7,7)这是一项关于创建一种分配给表达式中的变量的方法的建议.
没有提到在分配的LHS中使用它。
https://stackoverflow.com/questions/65005973
复制相似问题