【问题标题】:An if statement to check within try statement in Python, need the code to execute in case an exception is raised as well在 Python 中的 try 语句中检查的 if 语句,需要在引发异常的情况下执行代码
【发布时间】:2015-01-23 13:53:11
【问题描述】:

我在这里有点难过。这是一段 Python 代码:

try:
    if parse[index+1][0] != "5":
        individual_services+=[individual_services_cur]
        individual_services_cur=[]
except IndexError:
    warning("Reached end of file. No next element")
    individual_services+=[individual_services_cur]
    individual_services_cur=[]

基本上,如果parse 中的下一个元素不是“5”或者不是“5”,我希望这两个操作(将individual_services_cur 列表添加到individual_services 列表和清除individual_services_cur 列表)发生'不存在(基本上是文件的结尾)。

我想知道是否有一种更优雅(甚至可能是他们所说的“pythonic”)的方式来编写此代码,例如,无需将这两个动作编写两次。我想不出finallyelse 语句有什么好的解决方案,而且我似乎无法摆脱try 语句,因为一旦到达文件末尾,IndexError 异常就会不可避免地引发。

【问题讨论】:

  • 看起来你想要发生的两件事根本不依赖于if parse[index+1][0] != "5"——所以只需将它排除在外(和try/except)并执行其中的两件事。
  • @martineau:这不是真的,如果元素是“4”那么代码不会运行
  • @Highstaker 以下任何答案对您有帮助吗?如果是,请选择一个作为您的答案。

标签: python if-statement python-3.x try-catch


【解决方案1】:

您可以使用中间变量来执行您需要的检查。

try:
    value_to_check = parse[index+1][0]

except IndexError:
    warning("Reached end of file. No next element")
    value_to_check = None
finally:
    if value_to_check != "5":
        individual_services+=[individual_services_cur]
        individual_services_cur=[]

【讨论】:

    【解决方案2】:

    另一个想法:

    update_i_s = True
    
    try:
        update_i_s= parse[index+1][0] != "5"
    except IndexError:
        warning("Reached end of file. No next element")
    finally:
        if update_i_s:
            individual_services.append([individual_services_cur]) if flag
            individual_services_cur=[]
    

    flag=True 仅在文件只有一行的情况下才需要,并且只需要在开头设置一次(所以不要将其放入任何循环中)。


    编辑:

    顺便说一句,如果finally 块可能会失败,您可能需要执行以下操作:

    try:
        try:
            update_i_s= parse[index+1][0] != "5"
        except IndexError:
            warning("Reached end of file. No next element")
        finally:
            if update_i_s:
                individual_services.append([individual_services_cur]) if flag
                individual_services_cur=[]
    except Exception:
        warning("failed to update individual_services")
        raise
    

    【讨论】:

      【解决方案3】:

      您可以在这两种情况下分配一个变量,然后检查一次。

      badstuff = False
      try:
          if parse[index+1][0] != "5":
              badstuff = True
      except IndexError:
          warning("Reached end of file. No next element")
          badstuff = True
      
      if badstuff:
          individual_services+=[individual_services_cur]
          individual_services_cur=[]
      

      如果它适合您,您可以将 if badstuff: 放在 finally 块中,具体取决于您的其余代码正在做什么。

      或者,将individual_services 的东西放在一个函数中,然后在两个地方都调用它。

      【讨论】:

      • 我曾想过使用这样的单独变量,但感觉不是很“pythonic”的方式。也许我不应该太在意它……
      • 不要太担心它是pythonic是非常pythonic的。
      【解决方案4】:

      怎么样

      last = len(parse) - 1
      
      if index == last or parse[index + 1][0] != "5":
          individual_services.append(individual_services_cur)
          individual_services_cur = []
      

      【讨论】:

        【解决方案5】:

        或者跳出框框思考一下:

        if index + 1 not in (index for index, value in enumerate(parse) if value[0] == '5'):
            individual_services+=[individual_services_cur]
            individual_services_cur=[]
        

        其中(index for index, value in enumerate(parse) if value[0] == '5') 是一个生成器,它生成每行的行号,其中第一个字符为“5”。相当于这样:

        def has_5s(p):
            '''Yield line numbers that begin with a 5'''
            for index, line in enumerate(p):
                yield index if line[0] == '5'
        
        if index + 1 not in has_5s(parse):
            individual_services+=[individual_services_cur]
            individual_services_cur=[]
        

        您只是检查以下行号 (line + 1) 是否是生成器生成的这些行号之一。由于enumerate 和生成器本身很懒,这应该非常快。

        【讨论】:

          猜你喜欢
          • 2022-08-19
          • 2021-03-31
          • 2021-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-05
          • 2017-10-26
          • 1970-01-01
          相关资源
          最近更新 更多