【问题标题】:What are the python builtin __exit__ argument types?python 内置的 __exit__ 参数类型是什么?
【发布时间】:2020-03-07 12:51:28
【问题描述】:

类有一个可定义的函数__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 参数,该参数在issubclassSyntaxError 的构造函数中上下文使用,由此推断exc_type 确实是某种Exception,@ 987654334@ 继承自。

exc_val

另外,TracebackException 类是一个 exc_value 参数,它与我们的 exc_val 相匹配,它似乎具有各种属性,例如 __cause____context__,以及所有在 @987654340 中定义的其他属性@ 本身。这让我觉得参数本身就是TracebackException的一个实例。

exc_tb

Python 定义了一个使用exc_tb 作为参数的walk_tb 函数(从docs.python.org 手动跟踪),并且该对象似乎具有可以跟踪的tb_frametb_linenotb_next 属性回到typeshed 库中的TracebackType 类。

想法?

【问题讨论】:

    标签: python python-3.x exception with-statement traceback


    【解决方案1】:

    exc_type 是异常的类。 exc_val 是异常实例。 exc_tb是一个traceback对象,在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 中将旧式类作为异常引发(!)

    【讨论】:

    • 我们从哪里导入TrackbackType?
    • @Mentos1386 从types 模块导入,不要与typing 模块混淆。
    • exit的返回类型注解应该是Optional[bool]吗? python.org/dev/peps/pep-0343/#id38
    • @Laurenz typeshed used bool github.com/python/typeshed/blob/… 我想返回 None 代替 False 没有实际区别,但它只是因为鸭子类型而起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2022-11-20
    • 2017-02-12
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多