在 try/ except 块中创建变量是否被认为是一种不好的做法?

Art*_*tur 4 python exception try-catch

None让我们考虑这个示例 - 返回列表中第一个值的索引li(如果存在)或最后一个元素的索引(如果None不存在于li.

我可以检查列表中是否有 None,但使用 ifs 不是首选方式 - Dive Into Python 鼓励使用异常,因为据说它们更快并使代码更清晰(请参阅问题)。所以我采取了三种方法:

1.

try:
    my_index = li.index(None)
except ValueError:
    my_index = len(li) - 1

print my_index
Run Code Online (Sandbox Code Playgroud)

my_index在 try/ except 块内声明。更少的行数,没有多余的声明。可能的问题 - 不同的异常类型将导致不创建my_index脚本并使其崩溃print

2.

my_index = None  # or anything else
try:
    my_index = li.index(None)
except ValueError:
    my_index = len(li) - 1

print my_index
Run Code Online (Sandbox Code Playgroud)

my_index在 try/except 之前声明,并且无论发生什么异常都会分配一个值。缺点——更多的线条,看起来多余。

3. 编辑:不起作用 - 无论 try/ except 结果如何,finally 都会被执行

try:
    my_index = li.index(None)
except ValueError:
    my_index = len(li) - 1
finally:
    my_index = None  # or anything else

print my_index
Run Code Online (Sandbox Code Playgroud)

优点 - 总是有效(或者至少我这么认为)。缺点 - 我从来没有见过有人使用finally我的整个 Python 经验,这一定是有原因的。

这些方法中哪一个被认为是首选且Pythonic 的方法?也许有更好的解决方案?

dec*_*eze 5

try:
    my_index = li.index(None)
except ValueError:
    my_index = len(li) - 1

print my_index
Run Code Online (Sandbox Code Playgroud)

可能的问题 - 不同的异常类型将导致不创建my_index脚本并使其崩溃print

呃,不。如果引发任何其他异常,整个代码块将被中止,因为异常会冒泡到调用者。因此,如果ValueError引发任何其他异常类型,print则永远不会执行。这是一个非常理智的行为:您处理您期望和可以处理的错误,并让其他错误导致整个块(可能是整个脚本)中止。这是满足您需求的最明智、最简洁的解决方案。