【问题标题】:Use exception variable in finally block在 finally 块中使用异常变量
【发布时间】:2021-03-02 21:49:29
【问题描述】:

运行此示例函数时:

from typing import Tuple, Any, Optional

def func() -> Tuple[Any, Optional[Exception]]:
    exc = None
    ret = None
    try:
        # code here, if successful assign result to `ret`
        ret = "Result"
        # comment this line out and the code works
        raise Exception
    except Exception as exc:
        exc.__traceback__ = None
        # Error logging here
        pass
    finally:
        return ret, exc

print(func())  # expected: ("Result", <Exception instance>)

最后一行 (return ret, exc) 引发 UnboundLocalError: local variable 'exc' referenced before assignment 即使 exc 明确绑定在函数的第一行 (exc = None)。这可以通过更改except-clause 来解决,如下所示:

except Exception as exc1:
    exc = exc1
    exc.__traceback__ = None
    # Error logging here
    pass

问题

  1. 是否可以避免使用另一个变量(在我的示例中为 exc1)同时仍然避免使用 UnboundLocalError
  2. 为什么except &lt;Exception&gt; as &lt;var&gt; 语句会“吞下”已定义的局部变量?

【问题讨论】:

    标签: python python-3.x exception scope try-catch


    【解决方案1】:

    这个案例在8.4. The try statement中有所描述:

    当使用 as target 分配异常时,它会在 except 子句的末尾被清除。这好像

    except E as N:
       foo
    

    被翻译成

       try:
           foo
       finally:
           del N
    

    这意味着必须将异常分配给不同的名称才能在 except 子句之后引用它。异常被清除是因为附加了回溯,它们与堆栈帧形成一个引用循环,使该帧中的所有本地人保持活动状态,直到下一次垃圾回收发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 2010-10-03
      • 2014-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多