Python 内置 __exit__ 参数类型是什么?

问题描述 投票:0回答:2

类具有可定义的函数

__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
参数,该参数在
issubclass
中的构造函数中与
SyntaxError
一起使用,这推断
exc_type
确实是某种
Exception
,其中
 SyntaxError
继承自.

exc_val

此外,在

TracebackException
类中有一个
exc_value
参数,与我们的
exc_val
匹配,它似乎具有各种属性,如
__cause__
__context__
以及所有在
TracebackType
本身中定义的其他属性。这让我认为参数本身就是
TracebackException
的实例。

exc_tb

Python 定义了一个 walk_tb 函数,它使用

exc_tb
作为参数(从 docs.python.org 手动追踪),并且该对象似乎具有
tb_frame
tb_lineno
tb_next
属性,可以可以追溯到
TracebackType
 库中的 
typeshed
类。

想法?

python python-3.x exception with-statement traceback
2个回答
59
投票

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

一般来说应该是这样的

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

请注意,当上下文管理器下的代码没有引发异常时,仍会调用

__exit__
,并且参数将为
(None, None, None)
,因此所有三个参数都应注释为可选

那么它的正确注释应该如下所示:

from types import TracebackType
from typing import Optional, Type


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

您可能想知道为什么这个 API 具有三个参数,而其中两个可以从异常实例本身轻松确定。但情况并非总是如此,在旧版本的 Python 中,您可以将字符串作为异常引发,并且异常的

__traceback__
属性不存在 直到 Python 2.5。并且您仍然可以在 Python 2.7 中将旧式类作为异常引发 (!)


15
投票

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:
   ...

如果您想抑制上下文中引发的异常,则应从

True
返回
__exit__
,而在所有其他情况下则应返回
False

© www.soinside.com 2019 - 2024. All rights reserved.