当前位置: 首页 > 面试题库 >

在上下文管理器__enter __()中捕获异常

桑睿识
2023-03-14
问题内容

是否可以确保__exit__()即使有异常,也要调用该方法__enter__()

>>> class TstContx(object):
...    def __enter__(self):
...        raise Exception('Oops in __enter__')
...
...    def __exit__(self, e_typ, e_val, trcbak):
...        print "This isn't running"
... 
>>> with TstContx():
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __enter__
Exception: Oops in __enter__
>>>

编辑

这是我所能接近的…

class TstContx(object):
    def __enter__(self):
        try:
            # __enter__ code
        except Exception as e
            self.init_exc = e

        return self

    def __exit__(self, e_typ, e_val, trcbak):
        if all((e_typ, e_val, trcbak)):
            raise e_typ, e_val, trcbak

        # __exit__ code


with TstContx() as tc:
    if hasattr(tc, 'init_exc'): raise tc.init_exc

    # code in context

事后看来,上下文管理器可能不是最佳的设计决策


问题答案:

像这样:

import sys

class Context(object):
    def __enter__(self):
        try:
            raise Exception("Oops in __enter__")
        except:
            # Swallow exception if __exit__ returns a True value
            if self.__exit__(*sys.exc_info()):
                pass
            else:
                raise


    def __exit__(self, e_typ, e_val, trcbak):
        print "Now it's running"


with Context():
    pass

为了使程序以一种愉快的方式继续运行而不执行上下文块,您需要检查上下文块内的上下文对象,并且仅在__enter__成功后才做重要的事情。

class Context(object):
    def __init__(self):
        self.enter_ok = True

    def __enter__(self):
        try:
            raise Exception("Oops in __enter__")
        except:
            if self.__exit__(*sys.exc_info()):
                self.enter_ok = False
            else:
                raise
        return self

    def __exit__(self, e_typ, e_val, trcbak):
        print "Now this runs twice"
        return True


with Context() as c:
    if c.enter_ok:
        print "Only runs if enter succeeded"

print "Execution continues"

据我所知,您不能完全跳过with块。并请注意,此上下文现在吞没了其中的 所有
异常。如果您不希望吞下异常(如果__enter__成功),请签self.enter_ok__exit__return False如果是True



 类似资料:
  • 问题内容: 我有一个异步API,用于连接邮件并将其发送到SMTP服务器,该服务器具有一些设置并已删除。因此,它非常适合使用Python 3的。 虽然,我不知道是否可以写,因为它们都使用生成器语法来写。 这可能证明了这个问题(包含yield-base和async-await语法的混合,以演示异步调用和上下文管理器的yield之间的区别)。 目前在python中可能发生这种情况吗?以及如何使用该 语句

  • 要使人晓得智慧和训诲,分辨通达的言语。使人处事,领受智慧、仁义、公平、正直的训诲。使愚人灵明、使少年人有知识和谋略。使智慧人听见、增长学问、使聪明人得着智谋、使人明白箴言和譬喻、懂得智慧人的言词和谜语。敬畏耶和华使知识的开端,愚妄人藐视智慧和训诲。 上下文管理器 在《文件(1)》中提到,如果要打开文件,一种比较好的方法是使用with语句,因为这种方法,不仅结构简单,更重要的是不用再单独去判断某种异

  • Context managers for use with the with statement. 注解 When using Python 2.5, you will need to start your fabfile with from __future__ import with_statement in order to make use of the with statement (w

  • 问题内容: 我不明白为什么无法在此示例中模拟NamedTemporaryFile.name: 测试结果在: 问题答案: 您设置的模拟错误:不是上下文管理器,而是 返回 了一个上下文管理器。将您的设置行替换为: 这样您的测试就可以了。

  • 问题内容: 在这个问题中,我定义了一个包含上下文管理器的上下文管理器。完成此嵌套的最简单的正确方法是什么?我最后打电话了。但是,在中,我很确定我必须调用finally块,以防引发异常。如果出现问题,是否应该设置type_,value和traceback参数?我检查了,但找不到任何实用程序来帮助解决此问题。 来自问题的原始代码: 问题答案: 创建上下文管理器的简单方法是使用。像这样: 然后使用。语句

  • 本文向大家介绍Python多个上下文管理器,包括了Python多个上下文管理器的使用技巧和注意事项,需要的朋友参考一下 示例 您可以同时打开多个内容管理器: 它与嵌套上下文管理器具有相同的效果: