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


例如,若顾客要点香蕉冰沙,那我们首先得把香蕉切成好几份,然后用其中的两份来制作这道冰沙 。如果不够两份,那就抛出香蕉不足(OutOfBananas)异常 。下面用传统的写法实现这种逻辑:
def slice_bananas(count):    print(f'Slicing {count} bananas')    return count * 4class OutOfBananas(Exception):    passdef make_smoothies(count):    print(f'Making a smoothies with {count} banana slices')pieces = 0count = fresh_fruit.get('banana', 0)if count >= 2:    pieces = slice_bananas(count)try:    smoothies = make_smoothies(pieces)except OutOfBananas:    out_of_stock()还有一种传统的写法也很常见,就是把if/else结构上方那条pieces = 0的赋值语句移动到else块中 。
count = fresh_fruit.get('banana', 0)if count >= 2:    pieces = slice_bananas(count)else:    pieces = 0try:    smoothies = make_smoothies(pieces)except OutOfBananas:    out_of_stock()这种写法看上去稍微有点儿怪,因为if与else这两个分支都给pieces变量定义了初始值 。根据Python的作用域规则,这种分别定义变量初始值的写法是成立的 。虽说成立,但这样写看起来比较别扭,所以很多人喜欢用第一种写法,也就是在进入if/else结构之前,先把pieces的初始值给设置好 。
改用海象操作符来实现,可以少写一行代码,而且能够压低count变量的地位,让它只出现在if块里,这样我们就能更清楚地意识到pieces变量才是整段代码的重点 。
pieces = 0if (count := fresh_fruit.get('banana', 0)) >= 2:    pieces = slice_bananas(count)try:    smoothies = make_smoothies(pieces)except OutOfBananas:    out_of_stock()对于在if与else分支里面分别定义pieces变量的写法来说,海象操作符也能让代码变得清晰,因为这次不用再把count变量放到整个if/else块的上方了 。
if (count := fresh_fruit.get('banana', 0)) >= 2:    pieces = slice_bananas(count)else:    pieces = 0try:    smoothies = make_smoothies(pieces)except OutOfBananas:    out_of_stock()Python新手经常会遇到这样一种困难,就是找不到好办法来实现switch/case结构 。最接近这种结构的做法是在if/else结构里面继续嵌套if/else结构,或者使用if/elif/else结构 。
例如,我们想按照一定的顺序自动给客人制作饮品,这样就不用点餐了 。下面这段逻辑先判断能不能做香蕉冰沙,如果不能,就做苹果汁,还不行,就做柠檬汁:
count = fresh_fruit.get('banana', 0)if count >= 2:    pieces = slice_bananas(count)    to_enjoy = make_smoothies(pieces)else:    count = fresh_fruit.get('apple', 0)    if count >= 4:        to_enjoy = make_cider(count)    else:        count = fresh_fruit.get('lemon', 0)        if count:            to_enjoy = make_lemonade(count)        else:            to_enjoy = 'Nothing'这种难看的写法其实在Python代码里特别常见 。幸好现在有了海象操作符,让我们能够轻松地模拟出很接近switch/case的方案 。
if (count := fresh_fruit.get('banana', 0)) >= 2:    pieces = slice_bananas(count)    to_enjoy = make_smoothies(pieces)elif (count := fresh_fruit.get('apple', 0)) >= 4:    to_enjoy = make_cider(count)elif count := fresh_fruit.get('lemon', 0):    to_enjoy = make_lemonade(count)else:    to_enjoy = 'Nothing'这个版本只比原来短五行,但是看起来却清晰得多,因为嵌套深度与缩进层数都变少了 。只要碰到刚才那种难看的结构,我们就应该考虑能不能改用海象操作符来写 。


推荐阅读