代码中难免存在复杂的if-else条件逻辑,简化条件表达式是一种非常实用的技巧,能够帮助我么提高代码的可读性,减少不必要的if-else嵌套结构。由于涉及的主题较广,将分为上下篇进行介绍,本篇文章和大家分享优化if-else结构的7个实用小技巧,下一篇文章将分享一些更高级的主题,比如利用面向对象中的多态机制优化if-else结构。
使用三元运算符
与标准的if-else语句相比,三元运算符更加简洁,可读性更高,适用于简单的条件判断逻辑。
before:
def get_discount_price(self, price):
if self.is_discount_good():
return price*0.8
else:
return price
after:
def get_discount_price(self, price):
return price*0.8 if self.is_discount_good() else price
提前return,去掉多余的else
同样是上面的例子,最后的else其实是多余的。正常情况下,商品是不打折的,如果发现顾客买的是打折商品就打8折。
before:
def get_discount_price(self, price):
if self.is_discount_good():
return price*0.8
else:
return price
after:
def get_discount_price(self, price):
if self.is_discount_good():
return price*0.8
return price
合并重复的条件片段
before:
def get_total_price(self, price, amount):
if self.is_discount_good():
price = price*0.95
total_price = price*amount
else:
total_price = price*amount
return total_price
after:
def get_total_price(self, price,amount):
if self.is_discount_good():
price = price*0.95
total_price = price*amount
return total_price
分解条件表达式
某些时候,我们的条件判断过于复杂,很难弄清楚这个条件判断的功能是什么,导致代码的可读性大大降低。这时候我们可以像处理过长的函数的时候那样,将复杂的条件判断提炼为独立函数,从而更清楚的表达自己的意图。
before:
def get_discount_price(self, price):
if date.today().strftime("%m%d")=="0618" or date.today().strftime("%m%d")=="1111":
return price*0.8
else:
return price
after:
def get_discount_price(self, price):
def is_special_day(date):
if date.today().strftime("%m%d")=="0618" or date.today().strftime("%m%d")=="1111":
return True
return False
if is_special_day(self.order_date):
return price*0.8
else:
return price
虽然我们的代码长度增加了,但是我们提炼了新的函数,可读性更高,也便于单元测试。
合并条件表达式
合并与分解是两个相反的动作,如果我们发现有一系列的检查条件,最终的行为却是一致的,就应该使用逻辑或与非,将他们合并为一个条件表达式,让逻辑更加清晰。
before:
def get_discount_price(self, price):
if self.tax_free_good():
return price*0.8
if self.s_discount_good():
return price*0.8
return price
既然免税商品和打折商品最后计算价格的时候都是打八折,那为什么不将他们合并到一个判断逻辑中呢?
after:
def get_discount_price(self, price):
if self.tax_free_good() or self.s_discount_good():
return price*0.8
return price
当然我们也反对强行合并条件表达式的做法,如果这些条件真的是彼此独立的,例如下一节员工工资发放的判断逻辑中,这些判断条件的确是彼此独立的,因此最好还是不要合并它们。
优化逻辑结构,让正常流程走主干
条件表达式通常有两种表现形式,第一种形式是:所有分支都属于正常行为;第二种形式则是:条件表达式中只有一种是正常行为,其他都是不常见的特殊情况。这两种表达式有着不同的用途,这一点应该通过代码表现出来。
before:
def get_pay_amount(self):
if self.isdead:
result = self.dead_amount()
else:
if self.is_dismiss:
result = self.dismiss_amount()
else:
if self.is_retired:
result = self.retired_amount()
else:
result = normal_pay_amount()
return result
上面计算工资的例子中,工资发放有多种情况,但是其中死亡、解雇、退休都是特殊的情况,而大多数的时候是按照正常情况发工资的,我们应该在代码中体现出来。
after:
def get_pay_amount(self):
if self.isdead:
return self.dead_amount()
if self.is_dismiss:
return self.dismiss_amount()
if self.is_retired:
return self.retired_amount()
return normal_pay_amount()
换句话说,第一种形式中,我们潜在的表达了,我们对所有的if分支和else分支的重要程度是一样的,而第二种情况中,我们表达的是,if分支中的情况非常罕见,如果发生了做一些特别的处理,而大多数的时候我们都走主干流程,如此一来,可读性就高了。
使用枚举
在某些时候,使用枚举也可以优化if-else逻辑分支,这样做的好处在于维护起来更加方便,只需要维护一个枚举字典就好了,无需更改if-else逻辑分支。
before:
def print_order_info(status_code):
if status_code=="0":
print('订单未支付')
elif status_code=="1":
print("订单已支付")
elif status_code=="2":
print("订单已发货")
elif status_code=="3":
print("订单已收货")
elif status_code=="4":
print("订单已退货")
after:
status_dict = {"0":'订单未支付',
"1":"订单已支付",
"2","订单已发货",
"3":"订单已收货",
"4":"订单已退货"
}
def print_order_info(status_code):
return status_dict.get(status_code)
欢迎关注我的公众号“数据科学杂谈”,原创技术文章第一时间推送。