<p><a href="https://www.python.org/dev/peps/pep-0572/" rel="nofollow noreferrer">PEP 572</a>包含许多细节,尤其是第一个问题。我将尽量简明地总结/引用政治公众人物最重要的部分:</p>
<p><strong>基本原理</strong></p>
<p>允许在理解(如列表理解)和lambda函数中使用这种形式的赋值,而传统的赋值是被禁止的。这也可以促进交互调试,而无需进行代码重构。</p>
<p><strong>推荐的用例示例</p>
<p><em>a)获取条件值</em></p>
<p>例如(在Python 3中):</p>
<pre><code>command = input("> ")
while command != "quit":
print("You entered:", command)
command = input("> ")
</code></pre>
<p>可以变成:</p>
<blockquote>
<pre><code>while (command := input("> ")) != "quit":
print("You entered:", command)
</code></pre>
</blockquote>
<p><em>b)简化列表理解</em></p>
<p>例如:</p>
<blockquote>
<p><code>stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]</code></p>
</blockquote>
<p>可以变成:</p>
<blockquote>
<p><code>stuff = [[y := f(x), x/y] for x in range(5)]</code></p>
</blockquote>
<p><strong>语法和语义</p>
<blockquote>
<p>In any context where arbitrary Python expressions can be used, a <strong>named expression</strong> can appear. This is of the form <code>name := expr</code> where <code>expr</code> is any valid Python expression, and name is an identifier.</p>
<p>The value of such a named expression is the same as the incorporated expression, with the additional side-effect that the target is assigned that value</p>
</blockquote>
<p><strong>与常规赋值语句的区别</strong></p>
<p>除了是表达式而不是语句之外,PEP中还提到了一些差异:表达式赋值从右向左,逗号周围的优先级不同,并且不支持:</p>
<ul>
<li>多个目标</li>
</ul>
<blockquote>
<pre><code>x = y = z = 0 # Equivalent: (z := (y := (x := 0)))
</code></pre>
</blockquote>
<ul>
<li>分配不到单个名称:</li>
</ul>
<blockquote>
<pre><code># No equivalent
a[i] = x
self.rest = []
</code></pre>
</blockquote>
<ul>
<li>可装箱/拆箱</li>
</ul>
<blockquote>
<pre><code># Equivalent needs extra parentheses
loc = x, y # Use (loc := (x, y))
info = name, phone, *rest # Use (info := (name, phone, *rest))
# No equivalent
px, py, pz = position
name, phone, email, *other_info = contact
</code></pre>
</blockquote>
<ul>
<li>内联类型批注:</li>
</ul>
<blockquote>
<pre><code># Closest equivalent is "p: Optional[int]" as a separate declaration
p: Optional[int] = None
</code></pre>
</blockquote>
<ul>
<li>不支持扩展分配:</li>
</ul>
<blockquote>
<pre><code>total += tax # Equivalent: (total := total + tax)
</code></pre>
</blockquote>