在Python中的调用代码中,在__enter__中捕获异常 [英] Catching an exceptions in __enter__ in the calling code in Python

查看:219
本文介绍了在Python中的调用代码中,在__enter__中捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法可以在上下文管理器的 __输入__ 方法中捕获异常,而不用阻止一个尝试

  class TstContx(object):
def __enter __(self):
raise异常(我想抓住这个异常)
def __exit __(self,e_typ,e_val,trcbak):
pass


with TstContx():
raise异常(我不想抓住这个异常)
pass
/ pre>

我知道我可以在 __中输入__()本身的异常,但是可以访问该错误从包含语句的函数



表面上的问题 __ exit __ 被调用,而不是处理 __输入__ 代码与 语句包围。



...显然动机应该更清晰。具有语句的正在为完全自动化的过程设置一些日志记录。如果程序在登录设置之前失败,那么我不能依赖日志来通知我,所以我必须做一些特别的事情。而且我宁可实现效果,而无需添加更多缩进,如下所示:

  try:
with TstContx ():
尝试:
打印做某事
除了异常:
打印这里我将处理在声明正文中生成的异常
除了异常:
print这里我将处理在__enter__中出现的异常(我也假设__exit__)

使用两个 try 块的另一个缺点是处理 __中的异常的代码输入__ 在块的的后续正文中处理异常的代码之后。

解决方案

您可以使用 try / 除内的 __输入__ ,然后将异常实例另存为 TstContx 类的实例变量,允许您在中使用块访问它:

  class TstContx(object )
def __enter __(self):
self.exc = None
try:
raise异常(我想抓住这个异常)
except例如e:
self.exc = e
return self

def __exit __(self,e_typ,e_val,trcbak):
pass

with TstContx()as tst:
如果tst.exc:
print(我们捕获了一个例外:'%s'%tst.exc)
raise异常(I don不想收到这个例外)

输出:

 我们发现了一个例外:'我想抓住这个异常'。 
追溯(最近的最后一次调用):
文件./torn.py,第20行,< module>
raise异常(我不想捕获此异常)
异常:我不想捕获此异常

不知道为什么你想这样做,虽然....


Is there a way I can catch exceptions in the __enter__ method of a context manager without wrapping the whole with block inside a try?

class TstContx(object):
    def __enter__(self):
        raise Exception("I'd like to catch this exception")
    def __exit__(self, e_typ, e_val, trcbak):
        pass


with TstContx():
    raise Exception("I don't want to catch this exception")
    pass

I know that I can catch the exception within __enter__() itself, but can I access that error from the function that contains the with statement?

On the surface the question Catching exception in context manager __enter__() seems to be the same thing but that question is actually about making sure that __exit__ gets called, not with treating the __enter__ code differently from the block that the with statement encloses.

...evidently the motivation should be clearer. The with statement is setting up some logging for a fully automated process. If the program fails before the logging is set up, then I can't rely on the logging to notify me, so I have to do something special. And I'd rather achieve the effect without having to add more indentation, like this:

try:
    with TstContx():
        try:
            print "Do something"
        except Exception:
            print "Here's where I would handle exception generated within the body of the with statement"
except Exception:
    print "Here's where I'd handle an exception that occurs in __enter__ (and I suppose also __exit__)"

Another downside to using two try blocks is that the code that handles the exception in __enter__ comes after the code that handles exception in the subsequent body of the with block.

解决方案

You can catch the exception using try/except inside of __enter__, then save the exception instance as an instance variable of the TstContx class, allowing you to access it inside of the with block:

class TstContx(object):
    def __enter__(self):
        self.exc = None
        try:
            raise Exception("I'd like to catch this exception")
        except Exception as e:
            self.exc = e 
        return self

    def __exit__(self, e_typ, e_val, trcbak):
        pass    

with TstContx() as tst:
    if tst.exc:
        print("We caught an exception: '%s'" % tst.exc)
    raise Exception("I don't want to catch this exception")

Output:

We caught an exception: 'I'd like to catch this exception'.
Traceback (most recent call last):
  File "./torn.py", line 20, in <module>
    raise Exception("I don't want to catch this exception")
Exception: I don't want to catch this exception

Not sure why you'd want to do this, though....

这篇关于在Python中的调用代码中,在__enter__中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆