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

Order of evaluation of assignment expressions (walrus operator)

我有以下表达式:

>>> a = 3
>>> b = 2
>>> a == (a := b)
False

现在,a == 2 手术后,如预期。结果就是我想要的,即在赋值之前将 a 与赋值的 RHS 进行比较。

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

>>> a = 3
>>> b = 2
>>> (a := b) == a
True

PEP-572, relative precedence section. The next section, change to evaluation order 中似乎没有任何与此极端情况直接相关的内容提到评估顺序是从左到右。这就是这里发生的事情吗(存储 a 的值,更新它,并与更新 a 进行比较,然后与它的新值进行比较)?

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

这些 PEP 部分都与此无关。您只有一个 == 比较,一般 Evaluation order 适用:"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 ...} 这样的字典理解在 X 之前评估了 Y,这违反了一般的从左到右的规则,并且反对像 {X: Y} 这样已经评估了 XY 之前。考虑一下:

>>> a, b = 3, 2
>>> {a: (a := b) for _ in '_'}
{3: 2}

按照旧行为,它会导致 {2: 2}。考虑到当 := 可用时人们可能会写类似的东西,这就成了一个更大的问题。