在Haskell中,我们有异步异常。我们可以使用 throwTo
在另一个线程中引发任何异常:
为了能够像“在获得锁后总是释放锁”这样的保证下编写代码,我们使用 mask
运行其中仅在计算阻塞时才能接收异步异常的代码:
还有一个更强大的 uninterruptibleMask
,其中在屏蔽计算期间根本不会引发异步异常:
屏蔽用于实现更高层次的抽象,例如 bracket
:
如果我理解正确,Python会以(较不通用的)形式出现异步异常,最明显的表现形式是 KeyboardInterrupt
:
该文档对于何时可能发生“检查中断”并不准确,但似乎暗示着在程序执行的任何时候都可能引发KeyboardInterrupt
。如此看来,Python的异步异常也伴随着维护正确性的所有细微困难。
例如,考虑这样的模式:
x = None
try:
x = acquire()
do_something(x) # (1)
finally:
if x is not None: # (2)
release(x)
如果在(1)
期间引发任何异常,那么我们可以保证 finally
块的内容将被执行。但是,如果在KeyboardInterrupt
期间输入(2)
会发生什么呢?从根本上讲,如果没有掩盖异常的方式,就无法保证在存在非常规异常的情况下对资源进行清理。是否为此提供了一些便利,还是我们依赖ostrich algorithm?
最佳答案
这就是上下文管理器的作用。
with acquire() as x:
do_something(x)
acquire
返回一个对象,该对象的类型定义__enter__
方法和x
方法,该方法将返回绑定(bind)到__exit__
的值,该方法将在with
语句的末尾执行,无论该语句如何退出。