且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

":="语法和赋值表达式:什么以及为什么?

更新时间:2022-01-30 22:14:58

PEP 572 包含许多细节,尤其是对于第一个问题.我将尝试简要地总结/引用PEP的一些最重要的部分:

PEP 572 contains many of the details, especially for the first question. I'll try to summarise/quote concisely arguably some of the most important parts of the PEP:

理论上

允许在理解范围内使用这种形式的赋值,例如列表理解和禁止传统赋值的lambda函数.这也可以简化交互式调试,而无需重构代码.

Allowing this form of assignment within comprehensions, such as list comprehensions, and lambda functions where traditional assignments are forbidden. This can also facilitate interactive debugging without the need for code refactoring.

推荐的用例示例

a)获取条件值

例如(在Python 3中):

for example (in Python 3):

command = input("> ")
while command != "quit":
    print("You entered:", command)
    command = input("> ")

可以成为:

while (command := input("> ")) != "quit":
    print("You entered:", command)

b)简化列表理解

例如:

stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]

可以成为:

stuff = [[y := f(x), x/y] for x in range(5)]

语法和语义

在可以使用任意Python表达式的任何情况下,都会出现命名表达式.格式为name := expr,其中expr是任何有效的Python表达式,名称是标识符.

In any context where arbitrary Python expressions can be used, a named expression can appear. This is of the form name := expr where expr is any valid Python expression, and name is an identifier.

这样的命名表达式的值与合并的表达式相同,另外还有一个副作用,即为目标分配了该值

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

与常规分配陈述的区别

除了是表达式而不是语句外,PEP中还提到了一些区别:表达式分配从右到左,在逗号周围具有不同的优先级,并且不支持:

In addition to being an expression rather than statement, there are several differences mentioned in the PEP: expression assignments go right-to-left, have different priority around commas, and do not support:

  • 多个目标
x = y = z = 0  # Equivalent: (z := (y := (x := 0)))

  • 分配的名称不单一:
# No equivalent
a[i] = x
self.rest = []

  • 可重复包装/拆包
# 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

  • 内联类型注释:
# Closest equivalent is "p: Optional[int]" as a separate declaration
p: Optional[int] = None

  • 不支持扩展分配:
total += tax  # Equivalent: (total := total + tax)