python 内置的 __exit__ 参数类型是什么?

ark*_*k0n 16 python exception with-statement traceback python-3.x

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

它需要所需的参数:

def __exit__(self, exc_type, exc_val, exc_tb):
Run Code Online (Sandbox Code Playgroud)

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

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

def __exit__(self, exc_type: Exception, exc_val: TracebackException, exc_tb: TracebackType):
Run Code Online (Sandbox Code Playgroud)

exc_type

蟒限定了TracebackException一个接受一个类exc_type,其中内容使用在构造参数issubclassSyntaxError,这推断出exc_type确实是某种Exception,其SyntaxError从继承。

exc_val

此外,在TracebackException类是exc_value符合了我们的说法exc_val似乎有不同的属性,如__cause____context__和那些在所有定义的其他属性TracebackType本身。这让我觉得参数本身就是TracebackException.

exc_tb

蟒限定walk_tb函数使用exc_tb作为参数(手动地从跟踪docs.python.org),并且该对象似乎具有tb_frametb_linenotb_next其可追溯到一个属性TracebackType在类typeshed库。

想法?

wim*_*wim 21

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: ...
Run Code Online (Sandbox Code Playgroud)

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

  • @Mentos1386 从“types”模块导入它,不要与“typing”模块混淆。 (2认同)

Ant*_*hon 8

mypy 第 4885 期中,Jelle Zijlstra 提供了__exit__.

适应您的参数名称和适当的导入:

from typing import Optional, Type
from types import TracebackType

def __exit__(
    self,
    exc_type: Optional[Type[BaseException]],
    exc_val: Optional[BaseException],
    exc_tb: Optional[TracebackType],
) -> bool:
   ...
Run Code Online (Sandbox Code Playgroud)

如果您想抑制在上下文中和所有其他情况下引发的异常,您应该返回Truefrom 。__exit__False