一旦进入finally
子句,是否可以判断是否存在异常?类似于:
try:
funky code
finally:
if ???:
print('the funky code raised')
我想让这样的东西更干些:
try:
funky code
except HandleThis:
# handle it
raised = True
except DontHandleThis:
raised = True
raise
else:
raised = False
finally:
logger.info('funky code raised %s', raised)
我不喜欢它需要捕获一个异常,您不打算处理它,只需要设置一个标志。
由于有些comments在MCVE中要求更少的“M”,这里有更多关于用例的背景知识。实际的问题是关于日志级别的提升。
logger.exception
在这里没有帮助。因此,代码在日志捕获上下文(设置自定义处理程序以截取日志记录)下运行,并且某些调试信息会被重新记录:
try:
with LogCapture() as log:
funky_code() # <-- third party badness
finally:
mylog = mylogger.WARNING if <there was exception> else mylogger.DEBUG
for record in log.captured:
mylog(record.msg, record.args)
好吧,听起来你实际上只是想修改现有的上下文管理器,或者使用类似的方法:} 的东西,可以完全按照你的要求来做。但你可以自己做,比如:
logbook
实际上有一个名为^{原始响应
你在考虑这个问题。
你想处理这个异常-你通过设置一个标志来处理它。也许你不关心其他事情(这看起来是个坏主意),但是如果你关心在引发异常时做些什么,那么你就需要明确它。
您正在设置一个变量,但您希望异常继续,这意味着您真正希望的是从引发的异常引发您自己的特定异常:
这解决了:
MyPkgException
来捕获所有异常,以便它可以记录某些内容并以良好的状态退出,而不是以难看的堆栈跟踪考虑到在选择日志级别的问题中添加了额外的背景信息,这似乎很容易适应预期的用例:
使用contextmanager
您可以使用自定义contextmanager,例如:
然后在
try
中使用它:它仍然是一个附加变量,但是如果您想在多个地方使用它,那么重用它可能要容易得多。你不需要自己去切换。
使用变量
如果您不需要contextmanager,我将反转触发器的逻辑,并仅在发生异常时切换它。这样,对于不想处理的异常,就不需要
except
案例。最合适的位置是else
子句,如果try
没有引发异常,则输入该子句:正如已经指出的,您可以用所需的日志功能替换它(在本例中),而不是使用“toggle”变量:
当然,如果把它放在
try
的末尾(正如这里的其他答案所建议的那样),它也会起作用,但是我更喜欢else
子句,因为它有更多的含义(“只有在try
块中没有异常的情况下,代码才应该被执行”,并且从长远来看可能更容易维护。尽管它仍然比上下文管理器更需要维护,因为变量是在不同的地方设置和切换的。使用
sys.exc_info
(仅适用于未处理的异常)我想提到的最后一种方法可能对您不太有用,但可能对未来的读者有用,他们只想知道是否存在未处理的异常(在任何} :
except
块中捕获的或在except
块中引发的异常)。在这种情况下,可以使用^{相关问题 更多 >
编程相关推荐