首页 > 解决方案 > python 内置的 __exit__ 参数类型是什么?

问题描述

类有一个可定义的函数__exit__,允许实现上下文管理器。

它需要所需的参数:

def __exit__(self, exc_type, exc_val, exc_tb):

但我找不到这些论点是什么及其类型的明确定义。

这是我对它们是什么以及为什么的最佳猜测,但我不完全确定:

def __exit__(self, exc_type: Exception, exc_val: TracebackException, exc_tb: TracebackType):

exc_type

Python 定义了一个TracebackException接受exc_type参数的类,该参数在 with 内的构造函数中上下文issubclass使用,SyntaxError它推断这exc_type确实是某种继承自的 。ExceptionSyntaxError

exc_val

此外,在TracebackException该类中有一个exc_value与我们相匹配的参数,exc_val它似乎具有各种属性,如__cause____context__和其他属性,这些属性都是在TracebackType其自身中定义的。这让我觉得参数本身就是TracebackException.

exc_tb

Python 定义了一个用作参数的walk_tb函数(从docs.python.orgexc_tb手动跟踪),并且该对象似乎具有、和可以追溯到库中的类的属性。tb_frametb_linenotb_nextTracebackTypetypeshed

想法?

标签: pythonpython-3.xexceptionwith-statementtraceback

解决方案


exc_type是异常的类。 exc_val是异常实例。 exc_tb是一个回溯对象,其中有一个引用types.TracebackType

一般来说,应该是这样的

  • type(exc_val) is exc_type
  • exc_val.__traceback__ is exc_tb

请注意,__exit__当上下文管理器下的代码没有引发异常时,仍然会调用它,并且 args 将是(None, None, None)因此所有三个参数都应该注释为optional

然后它的正确注释应该如下所示:

def __exit__(self, exctype: Optional[Type[BaseException]],
             excinst: Optional[BaseException],
             exctb: Optional[TracebackType]) -> bool: ...

您可能想知道为什么这个 API 有三个参数,而其中两个参数可以通过异常实例本身轻松确定。但并非总是如此,在旧版本的 Python 中,您可以将字符串作为异常引发,并且异常的__traceback__属性直到 Python 2.5才出现。而且您仍然可以在 Python 2.7 中将旧式类作为异常引发(!)


推荐阅读