【问题标题】:Python: process flow avoiding nested IF statementsPython:避免嵌套 IF 语句的流程
【发布时间】:2016-07-28 13:44:15
【问题描述】:

我有一个过程(类),我分成几个步骤(方法)。只有上一步成功后,才能调用每一步。我创建了一个 run() 方法,它通过在调用下一个步骤之前检查每个步骤来运行该过程:

def run(self):
    status = False
    if step_1():
        if step_2():
            if step_3():
                etc... [several nested IFs]
                status = True
            else:
                self.logger.error('Error in step 3')
        else:
            self.logger.error('Error in step 2')
    else:
        self.logger.error('Error in step 1')
    return status

有没有更优雅的方式(设计模式?)来避免这些嵌套的 IF 语句?

非常感谢,

【问题讨论】:

    标签: python python-2.7 design-patterns


    【解决方案1】:

    您可以将您的步骤放在一个列表中:

    my_plan = (step1, step2, step3, ..., stepN)
    

    然后循环执行:

    for step in my_plan:
       if not step():
          print 'Error in %s' % step.__name__
          status = False
          break
    else:
        status = True
    

    【讨论】:

    • @JohnCarpenter 不要在 Python 上“修复”缩进。 for 可以有 else 语句,在这种情况下这是正确的做法。
    • @JohnCarpenter 请花一些时间与python docs
    • @JohnCarpenter 不,你的做法是在每一步之后而不是在循环之后将status 设置为True
    • @RikiLyng 如果您没有一致的参数列表,它会变得更加困难。将相同的参数列表传递给每个函数可能是值得的,即使它们不需要它。
    • 尝试编写这种管道确实需要您的函数采用一致的参数列表。否则,您几乎只剩下原始解决方案,其中涉及大量嵌套的 if 语句。考虑一下,理论上您可以使用对functools.partial 的调用来创建您的管道((step1, step2, ...))以在每个步骤中包含参数((partial(step1, arg1, arg2), partial(step2, arg1), ...)),但这会变得越来越难看。
    【解决方案2】:

    如果您没有太多步骤或不想将步骤函数按顺序排列,这是一种替代方法。

    def run(self):
        status = step_1():
        if status:
            status = step_2():
        if status:
            status = step_3():
    
        etc... [several IFs]
    
        if status is False:
            self.logger.error('Error')
    
        return status
    

    【讨论】:

      【解决方案3】:

      将其视为失败返回 False 而不是通过返回 True。

      def run(self):
          if not step_1():
              self.logger.error('Error in step 1')
              return False
          if not step_2():
              self.logger.error('Error in step 2')
              return False
          if not step_3():
              self.logger.error('Error in step 3')
              return False
          return True
      

      【讨论】:

      • 第二个运行所有步骤。如果前一个步骤成功,OP 特别只想运行下一步。您的第一种方法遇到了与嵌套 if 语句相同的问题,其中代码的增长远远超过了每一步的应有速度。 larsks 的解决方案是正确的。
      • 在第二个中,如果 step 返回 False(如果不是 steps[i]),那么它会打印错误并返回 False,从而打破循环。如果没有返回 False,它只会继续下一步。
      • 明白了。删除了那个。
      • 这更好,但它仍然遇到代码增长超过每一步所需的问题。它仍然不比 OP 的原始代码好。它只是水平增长而不是垂直增长。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多