Python高能小技巧:用海象操作符减少重复代码

导读:赋值表达式(assignment expression)是Python 3.8新引入的语法,它会用到海象操作符(walrus operator) 。这种写法可以解决某些持续已久的代码重复问题 。a = b是一条普通的赋值语句,读作a equals b,而a := b则是赋值表达式,读作a walrus b 。
【Python高能小技巧:用海象操作符减少重复代码】这个符号为什么叫walrus呢?因为把:=顺时针旋转90°之后,冒号就是海象的一双眼睛,等号就是它的一对獠牙 。
作者:布雷特·斯拉特金(Brett Slatkin)
来源:华章科技
Python高能小技巧:用海象操作符减少重复代码

文章插图
 
这种表达式很有用,可以在普通的赋值语句无法应用的场合实现赋值,例如可以用在条件表达式的if语句里面 。赋值表达式的值,就是赋给海象操作符左侧那个标识符的值 。
举个例子 。如果有一筐新鲜水果要给果汁店做食材,那我们就可以这样定义其中的内容:
fresh_fruit = {    'Apple': 10,    'banana': 8,    'lemon': 5,}顾客点柠檬汁之前,我们先得确认现在还有没有柠檬可以榨汁 。所以,要先查出柠檬的数量,然后用if语句判断它是不是非零的值 。
def make_lemonade(count):    print(f'Making {count} lemons into lemonade')def out_of_stock():    print('Out of stock!')count = fresh_fruit.get('lemon', 0)if count:    make_lemonade(count)else:    out_of_stock()这段代码看上去虽然简单,但还是显得有点儿松散,因为count变量虽然定义在整个if/else结构之上,然而只有if语句才会用到它,else块根本就不需要使用这个变量 。所以,这种写法让人误以为count是个重要的变量,if和else都要用到它,但实际上并非如此 。
我们在Python里面经常要先获取某个值,然后判断它是否非零,如果是就执行某段代码 。对于这种用法,我们以前总是要通过各种技巧,来避免count这样的变量重复出现在代码之中,这些技巧有时会让代码变得比较难懂 。Python引入赋值表达式正是为了解决这样的问题 。下面改用海象操作符来写:
if count := fresh_fruit.get('lemon', 0):    make_lemonade(count)else:    out_of_stock()新代码虽然只省了一行,但读起来却清晰很多,因为这种写法明确体现出count变量只与if块有关 。这个赋值表达式先把:=右边的值赋给左边的count变量,然后对自身求值,也就是把变量的值当成整个表达式的值 。
由于表达式紧跟着if,程序会根据它的值是否非零来决定该不该执行if块 。这种先赋值再判断的做法,正是海象操作符想要表达的意思 。
柠檬汁效力强,所以只需要一颗柠檬就能做完这份订单,这意味着程序只需判断非零即可 。如果客人点的是苹果汁,那就至少得用四个苹果才行 。按照传统的写法,要先从fresh_fruit这个字典里面查出苹果(apple)的数量(count),然后在if语句里,根据这个数量构造条件表达式(count >= 4) 。
def make_cider(count):    print(f'Making cider with {count} apples')count = fresh_fruit.get('apple', 0)if count >= 4:    make_cider(count)else:    out_of_stock()这段代码与刚才那个柠檬汁的例子一样,也过分突出了count变量的意义 。下面改用海象操作符,把代码写得更清晰一些 。
if (count := fresh_fruit.get('apple', 0)) >= 4:    make_cider(count)else:    out_of_stock()与刚才那个例子一样,修改之后的代码也比原来少了一行 。但是这次,我们还要注意另外一个现象:赋值表达式本身是放在一对括号里面的 。为什么要这样做呢?因为我们要在if语句里面把这个表达式的结果跟4这个值相比较 。
刚才柠檬汁的例子没有加括号,因为那时只凭赋值表达式本身的值就能决定if/else的走向:只要表达式的值不是0,程序就进入if分支 。但是这次不行,这次要把这个赋值表达式放在更大的表达式里面,所以必须用括号把它括起来 。当然,在没有必要加括号的情况下,还是尽量别加括号比较好 。
还有一种类似的逻辑也会出现刚才说的重复代码,这指的是:我们要根据情况给某个变量赋予不同的值,紧接着要用这个变量做参数来调用某个函数 。


推荐阅读