【问题标题】:Equivalence to a try / except / finally statement等效于 try / except / finally 语句
【发布时间】:2018-02-24 01:32:39
【问题描述】:

简而言之,来自 Python

一个try/except/finally语句,如:

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. 为什么它等同于嵌套表单?
  2. 可以写成没有finally的形式吗?

    是否等价于

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

谢谢。

【问题讨论】:

    标签: python python-3.x exception-handling try-catch programming-languages


    【解决方案1】:

    这是我用来避免为 finally 代码创建函数并不得不从两个不同的地方调用它的方法。

    try:
        pass
        pass
        1/0
        pass
        pass
        pass
        raise Exception('Success')
    except Exception, e:
        if e.message != 'Success':
            import traceback
            print traceback.format_exc()
    
        print 'in finally'
        print 'in finally'
        print 'in finally'
    
        if e.message != 'Success':
            raise
    
    
    

    Linux 上的输出:

    Traceback (most recent call last):
      File "./test_finally.py", line 34, in <module>
        1/0
    ZeroDivisionError: integer division or modulo by zero
    
    in finally
    in finally
    in finally
    Traceback (most recent call last):
      File "./test_finally.py", line 34, in <module>
        1/0
    ZeroDivisionError: integer division or modulo by zero
    
    shell returned 1
    

    【讨论】:

      【解决方案2】:
      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()
        

      就清理而言,总是发生并且永远不会发生两次,尽管异常链接和回溯之类的行为可能会有所不同。

      【讨论】:

      • 谢谢。你对第 1 部分和第 2 部分的回答是否也适用于 Java 的 try...catch..finally?
      • 如果原始语句只是try...finally,即没有catch,那么你在第2部分中给出的没有finally的等效形式可以在没有嵌套的情况下简化吗?没有 finally 的等效形式会是什么样子?
      【解决方案3】:

      不,您的替代代码与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 出现在前一行。如果 line 是关键的清理代码,那么只有 tryexcept 的程序将无法运行它。但是,如果您将清理代码放在 finally 块中,则无论代码的任何其他部分引发任何异常,都可以保证运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-19
        • 1970-01-01
        • 2012-06-25
        • 1970-01-01
        • 2011-09-29
        • 1970-01-01
        • 2013-12-06
        相关资源
        最近更新 更多