在finally块中使用异常变量

2024-09-28 20:57:00 发布

您现在位置:Python中文网/ 问答频道 /正文

运行此示例func时:

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-子句来解决:

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

问题

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

Tags: none示例hereasexceptioncodeanyresult
1条回答
网友
1楼 · 发布于 2024-09-28 20:57:00

这种情况在8.4. The try statement中描述:

When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if

except E as N:
   foo

was translated to

   try:
       foo
   finally:
       del N

This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

相关问题 更多 >