目录

海象表达式简明教程(Python 3.8)

今天要说的是在 Python3.8 中引入的新特性:海象运算符(Walrus operator),这是一个备受争议的特性,但它最后还是通过并发布了🤔

它的功能就是,将赋值语句(Statements)变成赋值表达式(Expression)。为此,我们先需要了解表达式(Expression)和语句(Statement)的区别

在编程语言里面你可以看到各种 Language Constructs,大体上可以分为 Expression 和 Statement 两大类。Expression 通常会进行求值并返回,Statement 则通常会执行一些操作,没有返回值

在 Python 里,赋值语句是 Statement,所以它并没有返回值,比如下面的 Python 代码

print(x = 5)

你会遇到这样的错误

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    print(x = 5)
    ~~~~~^^^^^^^
TypeError: print() got an unexpected keyword argument 'x'

而在 C/C++ 中,赋值语句是 Expression,会将赋值结果返回

#include <iostream>
using namespace std;

int main() {
  int a;
  cout << (a = 42) << "\n";
}

上面的代码会在 stdout 打印

42

语法上很简单,将 = 换成 := 即可

<NAME> := <EXPR>

Python 怕你乱用这个特性,因此 <NAME>必须是一个普通的变量名,不能是列表的某个元素(some_list[some_idx])或者是实例的某个属性(some_instance.some_field

海象表达式 <NAME> := <EXPR> 的求值规则如下

  1. 首先对 <EXPR> 进行求值
  2. 将求值的结果赋值给 <NAME>
  3. 求值的结果作为整个海象表达式的返回值

注意它的优先级比 , 高,但是比其他的都要低,所以经常需要在它旁边加上 () 提高优先级

在使用控制流结构的时候,只要是有可能返回 None 的函数调用,此时用 := 都是很好用的

  • 如果为 None,那么什么也不发生
  • 如果不为 None,那么可以直接使用绑定的变量

在没有海象表达式以前,大多数人的习惯会是:先用 = 绑定函数调用的结果到某个变量上,然后检查这个变量是否为 None

may_be_none = foo(...)
if may_be_none:
    ...
else:
    ...

但现在有了海象表达式,我们可以把他们合并起来

if maybe_none := foo(...):
    ...
else:
    ...