使用else子句处理异常

时间:2012-01-11 18:05:01

标签: python

Python教程states:

  

try ... except语句有一个可选的 else子句,其中,   在场的时候,必须遵循所有除了条款。它对代码很有用   如果try子句没有引发异常,则必须执行该操作。   例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()
     

使用 else子句比添加其他代码更好   到try子句,因为它避免意外捕获异常   这个代码不受try的保护而引发...除外   言。

问题1 >在阅读上述文档后,我仍然不明白为什么我们不能简单地将代码从 else子句移动到 try子句

问题2 > try子句如何可能意外捕获异常,因为所有捕获都是在 except子句中完成的,对吗?

4 个答案:

答案 0 :(得分:6)

您可以将else代码放在try套件中,但是您可以捕获可能在那里引发的任何异常。如果您不打算这样做,那将是“偶然的”,因此您链接到的文档的措辞。

最佳做法是在try块中放置尽可能少的代码,以便在发生错误时,您知道是什么操作导致它并且可以适当地处理它。如果在try块中有五行代码并且只期望其中一行代码引发异常,那么当您在一行中没有发生异常时,异常处理代码就会准备不足至。在这种情况下更好的是提出异常而不是以错误的方式处理它。

答案 1 :(得分:3)

如果您将代码从 else 移动到尝试,那么它将成为可能引发异常的“关键路径”的一部分。如果 f.readlines()引发某种异常(由于磁盘上的坏扇区而在读取文件时可能出现I / O错误),那么该错误将与您的一个错误混淆目前赶上(从技术上讲,“无法打开”错误消息在那时是错误的...因为打开文件可以在以后读取时失败;实际上打开它必须成功才能在处理它时遇到I / O错误

通常你会使用更像的模式:

foo = None
try:
    # some code to access/load/initialize foo from an external source
except ...:
    # handle various types of file open/read, database access, etc errors
else:
    foo = something

...以便您随后运行代码并只检查 foo是否为并使用它或 以你认为合适的方式解决它无法使用。

答案 2 :(得分:2)

两个问题的答案相似,

如果将代码移到try子句中,则无法确定异常的来源。因此,如果您有另一行代码产生意外的IOError,您可能会在没有的情况下搜索问题。

因此,为了更好地处理您的代码,您希望尽可能简化try中的行,使得catch尽可能地具体化。

答案 3 :(得分:1)

1)当然,您可以将代码从else子句移动到try子句中。您可以将其完全移出try块,但这样可以提供额外的灵活性,并进一步调整代码。此外,也许特定的错误被捕获。您可以列出可能发生的不同异常的整个负载,每个异常都有不同的语句。如果在try块中执行最后一行之后没有引发异常,那么else子句中的内容仍然会发生。例如打印成功的返回消息。 此外,try子句在垃圾收集管理和错误跟踪方面增加了一些额外的CPU开销,因此try子句之外的任何内容都不会以相同的方式受到保护,并且可以更有效地运行。

2)错误捕获非常具体。例如只有在运行f = open(arg,'r')行时引发IOError时,才会运行上例中的except子句。如果您想捕获任何形式的例外,请使用except Exception: