赋值表达式的求值顺序(海象运算符)

Mad*_*ist 8 python python-assignment-expression walrus-operator

我有以下表达:

>>> a = 3
>>> b = 2
>>> a == (a := b)
False
Run Code Online (Sandbox Code Playgroud)

现在,a == 2手术后,正如预期的那样。结果就是我想要的,即a在分配之前与分配的 RHS 进行比较。

颠倒等号运算符的顺序会颠倒结果:

>>> a = 3
>>> b = 2
>>> (a := b) == a
True
Run Code Online (Sandbox Code Playgroud)

PEP-572 相对优先级部分中似乎没有任何与此极端情况直接相关的内容。下一节,更改评估顺序提到评估顺序是从左到右。这就是这里发生的情况吗(存储 的值a,更新它,然后比较与 update a,然后与其新值进行比较)?

这种行为是在哪里定义的,它的可靠性如何?

don*_*ode 7

这些 PEP 部分都与此无关。您只需进行==比较,即可应用一般求值顺序“Python 从左到右求值表达式”。

因此,您(a := b) == a只需首先评估左侧,分配一些(a := b)内容a并评估相同的值。然后评估右侧a,这当然仍然是相同的(刚刚​​分配的)值,所以你得到True


关于这些 PEP 部分:

第一个 PEP 部分所说的是:=分组不如 紧密,因此如果您没有括号,==它将适用:

  • a == a := b意味着(a == a) := b(尝试分配比较时会出现语法错误)。
  • a := b == a意味着a := (b == a),其中您的值的b == a计算结果为False并被分配给a并成为整个表达式的结果。(请注意,在语句级别,您必须编写(a := b == a)。)

第二个 PEP 部分所做的只是指出一些已经存在但:=“更加明显”的不好的东西,因此他们建议最终修复它。问题是像之前{X: Y for ...}评估的字典理解,反对一般的从左到右规则和字典显示,就像之前已经按预期评估一样。考虑一下:YX{X: Y}XY

>>> a, b = 3, 2
>>> {a: (a := b) for _ in '_'}
{3: 2}
Run Code Online (Sandbox Code Playgroud)

如果采用这种旧行为,就会导致{2: 2}. 考虑到人们可能会在:=可用时写出类似的东西,这变得更加成为一个问题。