赋值表达式(assignment)是python3.8引入的语法,它会用到海象操作符(walrus operator)。如 a := b
就是赋值表达式,读作a walrus b。
举个例子。有一筐水果,用来榨果汁,内容定义如下:
fresh_fruit = {
'apple': 10,
'banana': 8,
'lemon': 5,
}
榨果汁之前,需要确认有没有对应的水果了,也就是查出数量,判断是否为0,代码如下:
def make_lemonade():
count = fresh_fruit.get('lemon', 0) # 查当前柠檬的数量
if count:
print("榨柠檬汁")
else:
print("数量不够")
上面代码的问题是:count只有if语句才用到,其他代码块用不到,这样写就显得代码冗余。
使用场景1
设想以下场景:如果获取某个值,然后判断是否为0,如果是就执行某段代码。这时候就用到赋值表达式了。如下:
def make_lemonade():
if count := fresh_fruit.get('lemon', 0):
print("榨柠檬汁")
else:
print("数量不够")
虽然只省了一行代码,逻辑却更加清晰,因为这样体现了count变量只与if有关。海象操作符的原理就是,把操作符右边的值赋给了count,然后再把count变量当成整个表达式的值,if根据它的值进行判断。
不仅可以判断是否非0,其他表达式一样可以。
例如,榨一杯苹果汁需要4个苹果,则代码如下:
def make_cider():
if (count := fresh_fruit.get('apple', 0)) >= 4:
print("榨苹果汁")
else:
print("数量不够")
注意这次赋值表达式加了括号,因为要与4进行比较再用if判断。
使用场景2
赋值表达式里的变量除了用在if判断里,还可以用在if和else下面的语句块里,如下:
def make_cider():
if (count := fresh_fruit.get('apple', 0)) >= 4:
print(f"有苹果{count}个")
print("开始榨苹果汁")
else:
print(f"有苹果{count}个")
print("数量不够")
使用场景3
还可以使用海象操作符模拟出类似switch/case 的方案。
假如要制作香蕉沙拉,香蕉不够就改为制作苹果汁,苹果还不够就制作柠檬汁,代码如下:
if (count := fresh_fruit.get('banana', 0)) >= 2:
print("制作香蕉沙拉")
elif (count := fresh_fruit.get('apple', 0)) >= 4:
print("制作苹果汁")
elif count := fresh_fruit.get('lemon', 0):
print("制作柠檬汁")
else:
print("都不够了")
使用场景4
使用海象操作符实现类似do/while循环结构。
假如要把所有的说过榨汁装到瓶子里,传统的循环代码如下:
def pick_fruit():
"""取水果的方法,一次取一种"""
pass
def make_juice():
"""制作果汁的方法"""
pass
bottles = [] # 装果汁的瓶子
while True:
fresh_fruit = pick_fruit()
if not fresh_fruit:
break
for fruit, count in fresh_fruit.items:
batch = make_juice()
bottles.append(batch)
上面代码的问题是比较笨重,写了一个无限循环,只能通过break跳出循环。
下面改用海象操作符:
bottles = [] # 装果汁的瓶子
while fresh_fruit := pick_fruit():
for fruit, count in fresh_fruit.items:
batch = make_juice()
bottles.append(batch)
要点:
- 赋值表达式通过海象操作符(:=)给变量赋值,并且让这个值成为这条表达式的结果,利用这个特性可以缩减代码。
- 如果赋值表达式是大表达式里的一部分,就需要括号括起来。
- 可以利用赋值表达式模拟出switch/case和do/while 结构的代码。
参考:
Effective Python 第二版