在 Python 中的 try 语句中检查的 if 语句,也需要执行代码以防引发异常

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 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=[]

基本上我希望这两个操作(将 individual_services_cur 列表添加到 individual_services 列表并清除 individual_services_cur 列表)在 [=15= 中的下一个元素时发生] 不是“5”或者它不存在(基本上是文件结尾)。

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

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

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 东西放在一个函数中,然后在两个地方都调用它。

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

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=[]

怎么样

last = len(parse) - 1

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

另一个想法:

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

或者跳出框框思考一下:

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 和生成器本身是惰性的,这应该非常快。