try语句的可选else子句的预期用途是什么?


当前回答

错误和异常#处理异常- docs.python.org

The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example: 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() The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.

其他回答

可以在finally子句中以通用的方式使用此构造来处理异常,而在没有异常时执行其他操作:

class TooManyRetries(RuntimeError):
    pass


n_tries = 0
max_retries = 2
while True:
    try:
        n_tries += 1
        if n_tries >= max_retries:
            raise TooManyRetries
        fail_prone_operation()
    except Exception1 as ex:
        # handle1
    except Exception2 as ex:
        # handle2
    except Exception3 as ex:
        # handle3
    except TooManyRetries as ex:
        raise
    else: # No exception
        n_tries = 0
    finally:
        common_restore_state()
        continue

    

else:块令人困惑并且(几乎)毫无用处。它也是for和while语句的一部分。

实际上,即使在if语句中,else:也可能被滥用,造成非常难以发现的错误。

考虑这一点。

   if a < 10:
       # condition stated explicitly
   elif a > 10 and b < 10:
       # condition confusing but at least explicit
   else:
       # Exactly what is true here?
       # Can be hard to reason out what condition is true

三思而后行。这通常是个问题。除非在if语句中,否则避免使用它,即使在if语句中,也要考虑记录else-条件,使其显式。

Try-except-else非常适合结合EAFP模式和duck-typing:

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()

您可能认为naïve代码是好的:

try:
  for v in x.cleanupSet:
    v.clenaup()
except AttributeError:
  pass

这是在代码中意外隐藏严重错误的好方法。我在那里输入了清理,但是让我知道的AttributeError正在被吞噬。更糟糕的是,如果我写对了,但清理方法偶尔被传递一个具有错误命名属性的用户类型,导致它在中途无声地失败并留下一个未关闭的文件,会怎样?祝你在调试时好运。

假设您的编程逻辑取决于字典中是否有具有给定键的条目。你可以使用if…来测试dict.get(key)的结果。其他的……或者你可以这样做:

try:
    val = dic[key]
except KeyError:
    do_some_stuff()
else:
    do_some_stuff_with_val(val)

即使你现在想不出它的用途,你可以打赌它一定会有用处的。下面是一个没有想象力的例子:

其他:

a = [1,2,3]
try:
    something = a[2]
except IndexError:
    print("out of bounds")
else:
    print(something)

没有其他的:

try:
    something = a[2]
except IndexError:
    print("out of bounds")

if "something" in locals():
    print(something)

在这里,如果没有抛出错误,则定义了变量something。您可以在try块之外删除它,但如果定义了变量,则需要进行一些混乱的检测。