:=
(海象运算符)是 Python 3.8 引入的一种新的赋值语法,也称为指定分配(又称为等号赋值或链接赋值)。
海象运算符的英文原名叫 Assignment Expresions ,即 赋值表达式。海象表达式由一个 :
和 一个 =
组成,即 :=
。我们一般称作 walrus operator(海象运算符),因为它看起来就是一个海象旋转 90° 而成。
语法结构
海象运算符的语法格式是:
(variable_name := expression)
:=
指定分配是 Python 3.8 引入的一种新的赋值语法,主要用于在表达式中声明和初始化局部变量。它主要用于简化代码并使其更易于阅读和维护。
使用场景
- 在表达式中声明并初始化
局部变量
。例如:
if (n := len(items)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
在这个例子中,n
是一个局部变量,它被声明并初始化为 len(items)
的返回值。然后,它被用作 if
语句的条件。
- 在
while
循环中声明并初始化迭代变量。例如:
for i, item in enumerate(items):
print(f"Item {i}: {item}")
在这个例子中,i
和 item
分别是循环迭代变量和当前迭代的元素。这样的语法使得循环更加简洁,因为你不必分别声明 i
和 item
变量,然后再将它们赋值给迭代器返回的元组。
- 在函数调用中声明并初始化参数变量。例如:
def greet(name: str) -> str:
return f"Hello, {name}"
print(greet(name := "Alice")) # prints "Hello, Alice"
在这个例子中,name
是函数的参数,它被声明并初始化为字符串 “Alice
”。这样的语法使得函数调用更加简洁,你不必分别声明 name
变量,然后再将其传递给函数。
- 在
if
条件表达式中声明并初始化变量。例如:
def get_status(code: int) -> str:
status = "OK" if (code := 200) else "Error"
return f"HTTP {code}: {status}"
print(get_status(200)) # prints "HTTP 200: OK"
print(get_status(404)) # prints "HTTP 404: Error"
在这个例子中,code
是一个局部变量,它被声明并初始化为函数参数的值。然后,它被用作条件表达式的条件,并在函数返回值中使用。
- 在读取文件
file
中使用:
fp = open("test.txt", "r")
while line := fp.readline():
print(line.strip())
循环的条件是 line := fp.readline()
。这意味着,只要当前行的内容不是 None
(即未到达文件末尾),循环就会继续执行。
整个过程中,fp
变量表示文件对象,而 line
变量表示当前行的内容。使用指定分配(:=
)语法使循环更加简洁,因为你不必分别声明 line
变量,然后再将其赋值给 fp.readline()
的返回值。
注意事项
- 定分配是 Python 3.8 中的新功能,因此如果你使用的是早于 Python 3.8 的版本,则无法使用这种语法。
- 指定分配只能用于局部变量的声明和初始化,而不能用于修改现有变量的值。例如,你不能这样写:
x := x + 1 # SyntaxError
如果你想要修改现有变量的值,你可以使用常规的赋值语法:
x = x + 1
- 指定分配只能用于局部作用域中,例如函数内部或循环内部。你不能在全局作用域中使用指定分配,例如在模块顶层或函数外部。
- 指定分配必须在表达式中使用,例如
条件表达式
、循环语句
或函数调用
。你不能在语句块中使用指定分配,例如在 if 语句或 for 循环中。 - 指定分配的左侧必须是未声明的局部变量。如果你尝试将指定分配用于已声明的变量,则会引发错误。
- 指定分配的右侧必须是有效的表达式,并且在执行时必须返回有效的值。否则,指定分配会引发错误。
- 指定分配的右侧可能会触发副作用,例如函数调用或数据库查询。在使用指定分配时,应该注意这些副作用可能对你的代码产生的影响。
- 在使用指定分配时,应该注意其与其他语言特性的交互。例如,指定分配可能会与其他语言特性的优先级冲突,例如运算符或括号。
- 指定分配可能不是所有 Python 程序员都熟悉的语法。因此,在使用指定分配时,应该注意其可读性,并考虑与团队成员和其他程序员讨论使用指定分配的适用性。
总的来说,使用指定分配需要注意语法和作用域的限制,以及可能产生的副作用和与其他语言特性的兼容性。