Python项目代码太多if-else? 这样优化才优雅!

浏览: 15504

代码中难免存在复杂的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)

                              欢迎关注我的公众号“数据科学杂谈”,原创技术文章第一时间推送。

                              image.png

                              推荐 0
                              本文由 ID王大伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
                              转载、引用前需联系作者,并署名作者且注明文章出处。
                              本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

                              0 个评论

                              要回复文章请先登录注册