等价于一个try /除外/最后语句

问题描述:

通过Python果壳中等价于一个try /除外/最后语句

一个try /除外/最后语句,如:

try: 
    ...guarded clause... 
except ...expression...: 
    ...exception handler code... 
finally: 
    ...clean-up code... 

相当于嵌套语句:

try: 
    try: 
     ...guarded clause... 
    except ...expression...: 
     ...exception handler code... 
finally: 
    ...clean-up code... 
  1. 为什么它相当于ŧ o嵌套形式?
  2. 它可以写成相当于没有finally的表单吗?

    是否等同于

    try: 
        ...guarded clause... 
    except ...expression...: 
        ...exception handler code... 
        ...clean-up code... 
    ...clean-up code... 
    

感谢。

  1. 因为这就是它的定义。因为这样定义它是有用的和标准的,并且因为没有其他有用的方式来定义它。
  2. 是的,但不是你做到这一点。

    try: 
        do_stuff() 
    except OneProblem: 
        handle_it() 
    except DifferentProblem: 
        handle_that() 
    finally: 
        cleanup() 
    

    相当于

    try: 
        try: 
         do_stuff() 
        except OneProblem: 
         handle_it() 
        except DifferentProblem: 
         handle_that() 
    except: 
        # Clean up if an unhandled exception happened, then restore the exception. 
        cleanup() 
        raise 
    # Also clean up if we're not propagating an exception. 
    cleanup() 
    

在清理总是在发生,从来没有发生两次方面,虽然之类的异常链和回溯行为可能不同。

+0

谢谢。第1部分和第2部分的答案也适用于Java的try ... catch..finally? – Tim

+0

如果最初的陈述只是尝试...最后,即没有赶上,可以在没有嵌套的情况下简化第2部分而不是最终给出的等价形式吗?没有最终的等效形式会是什么样子? – Tim

不,您的替代代码不完全等同于try/except/finally版本。要理解为什么,请考虑如果在示例的...exception handler code...部分中触发了第二个异常会发生什么情况。

这里有一个演示,显示问题:

try: 
    print('in try')  # guarded code 
    1/0     # oops, a bug 
except ZeroDivisionError: 
    print('top of except') # exception handling code 
    name_does_not_exist  # oops, the exception handling code is buggy too 
    print('end of except') # this is a bad place for cleanup code 
finally: 
    print('in finally') # this is a much better place to do cleanup 

输出:

in try 
top of except 
in finally 
Traceback (most recent call last): 

    File "<ipython-input-17-63590fc64963>", line 6, in <module> 
    name_does_not_exist  # oops, the exception handling code is buggy too 

NameError: name 'name_does_not_exist' is not defined 

注意,end of except消息永远不会被印刷,因为发生在上一行的NameError。如果行是重要的清理代码,只有tryexcept的程序将无法运行它。但是,如果您将清理代码放在finally区块中,则无论代码的任何其他部分出现任何异常,它都能保证运行。