python 内置 __exit__ 参数类型是什么?
What are the python builtin __exit__ argument types?
类 有一个可定义的函数 __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
class 接受一个 exc_type
参数,该参数在 issubclass
和 SyntaxError
的构造函数中上下文使用,这表明 exc_type
确实是某种 Exception
,SyntaxError
继承自
exc_val
此外,TracebackException
class 是一个 exc_value
参数,与我们的 exc_val
相匹配,它似乎具有 __cause__
等各种属性, __context__
,以及其他所有在 TracebackType
中定义的属性。这让我觉得参数本身就是 TracebackException
.
的一个实例
exc_tb
Python 定义了一个 walk_tb function that uses exc_tb
as an argument (manually traced from docs.python.org), and this object appears to have tb_frame
, tb_lineno
, and tb_next
attributes which can be traced back to a TracebackType
class in the typeshed
库。
想法?
exc_type
是异常的 class。 exc_val
是异常实例。 exc_tb
是回溯对象,在types.TracebackType
中有引用。
一般来说应该是
type(exc_val) is exc_type
exc_val.__traceback__ is exc_tb
请注意,当上下文管理器下的代码没有引发异常时,仍然会调用 __exit__
,并且参数将为 (None, None, None)
,因此所有三个参数都应注释为 可选.
那么它的正确注释应该如下所示:
def __exit__(self, exctype: Optional[Type[BaseException]],
excinst: Optional[BaseException],
exctb: Optional[TracebackType]) -> bool: ...
您可能想知道为什么这个 API 有三个参数,而其中两个参数可以从异常实例本身轻松确定。但它并不总是那样,在旧版本的 Python 中,您可以将字符串作为异常引发,而异常的 __traceback__
属性不存在 until Python 2.5。你仍然可以在 Python 2.7 (!)
中将旧式 classes 作为异常
在 mypy issue 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:
...
如果您想抑制在上下文中引发的异常,您应该从 __eixt__
return True
,在所有其他情况下 False
。
类 有一个可定义的函数 __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
class 接受一个 exc_type
参数,该参数在 issubclass
和 SyntaxError
的构造函数中上下文使用,这表明 exc_type
确实是某种 Exception
,SyntaxError
继承自
exc_val
此外,TracebackException
class 是一个 exc_value
参数,与我们的 exc_val
相匹配,它似乎具有 __cause__
等各种属性, __context__
,以及其他所有在 TracebackType
中定义的属性。这让我觉得参数本身就是 TracebackException
.
exc_tb
Python 定义了一个 walk_tb function that uses exc_tb
as an argument (manually traced from docs.python.org), and this object appears to have tb_frame
, tb_lineno
, and tb_next
attributes which can be traced back to a TracebackType
class in the typeshed
库。
想法?
exc_type
是异常的 class。 exc_val
是异常实例。 exc_tb
是回溯对象,在types.TracebackType
中有引用。
一般来说应该是
type(exc_val) is exc_type
exc_val.__traceback__ is exc_tb
请注意,当上下文管理器下的代码没有引发异常时,仍然会调用 __exit__
,并且参数将为 (None, None, None)
,因此所有三个参数都应注释为 可选.
那么它的正确注释应该如下所示:
def __exit__(self, exctype: Optional[Type[BaseException]],
excinst: Optional[BaseException],
exctb: Optional[TracebackType]) -> bool: ...
您可能想知道为什么这个 API 有三个参数,而其中两个参数可以从异常实例本身轻松确定。但它并不总是那样,在旧版本的 Python 中,您可以将字符串作为异常引发,而异常的 __traceback__
属性不存在 until Python 2.5。你仍然可以在 Python 2.7 (!)
在 mypy issue 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:
...
如果您想抑制在上下文中引发的异常,您应该从 __eixt__
return True
,在所有其他情况下 False
。