python - Python 是否具有与 Haskell 的 'mask' 或 'bracket' 函数等效的函数?

标签 python haskell asynchronous exception-handling

在 Haskell 中我们有异步异常;我们可以使用throwTo在另一个线程中引发任何异常:

throwTo :: Exception e => ThreadId -> e -> IO ()

throwTo raises an arbitrary exception in the target thread (GHC only).

为了能够编写带有“获取锁后总是释放锁”这样的保证的代码,我们有mask运行仅在计算阻塞时才能接收到异步异常的代码:

mask :: ((forall a. IO a -> IO a) -> IO b) -> IO b

Executes an IO computation with asynchronous exceptions masked. That is, any thread which attempts to raise an exception in the current thread with throwTo will be blocked until asynchronous exceptions are unmasked again.

和更强的uninterruptibleMask在屏蔽计算期间根本不会引发异步异常:

uninterruptibleMask :: ((forall a. IO a -> IO a) -> IO b) -> IO b

Like mask, but the masked computation is not interruptible

掩码用于实现更高级别的抽象,如 bracket :

bracket
    :: IO a         -- computation to run first ("acquire resource")
    -> (a -> IO b)  -- computation to run last ("release resource")
    -> (a -> IO c)  -- computation to run in-between
    -> IO c         -- returns the value from the in-between computation

When you want to acquire a resource, do some work with it, and then release the resource, it is a good idea to use bracket, because bracket will install the necessary exception handler to release the resource in the event that an exception is raised during the computation. If an exception is raised, then bracket will re-raise the exception (after performing the release).

如果我理解正确的话,Python 有一种(不太通用的)异步异常形式,最显着的表现形式是 KeyboardInterrupt。 :

Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly.

文档对于何时可能发生“检查中断”并不准确,但它似乎暗示 KeyboardInterrupt 可能会在程序执行的任何点引发.因此,Python 的异步异常似乎在维护正确性方面同样存在微妙的困难。

例如,考虑这样的模式:

x = None
try:
    x = acquire()
    do_something(x)    # (1)
finally:
    if x is not None:  # (2)
        release(x)

如果在 (1) 期间出现任何异常,那么我们可以确信 finally 的内容 block 将被执行。但是如果 KeyboardInterrupt(2) 期间会发生什么?

在没有屏蔽异步异常的情况下,似乎根本不可能保证资源清理。是否有一些设施,或者我们依赖 ostrich algorithm

最佳答案

这就是上下文管理器的用途。

with acquire() as x:
    do_something(x)

acquire 返回一个对象,其类型定义了一个 __enter__ 方法,该方法返回绑定(bind)到 x 的值,以及一个 __exit__ 方法,在 with 语句结束时执行,无论该语句如何退出。

关于python - Python 是否具有与 Haskell 的 'mask' 或 'bracket' 函数等效的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42167862/

相关文章:

haskell - 不明确的类型变量

parsing - 如何使用 Haskell 解析中缀而不是前缀?

javascript - 异步调用串行生成的函数

c# - 不允许发送或接收数据的请求,因为未连接套接字(仅当我第二次连接时)

python - 将 Python 解释器放入 Beamer 幻灯片中

python - 迭代器的意外行为

javascript - 使用 ajax 调用 Flask 服务器进行登录身份验证(管道损坏)

python - 获取 Tkinter 窗口大小

haskell - Lisp 有类似 Haskell 的 takeWhile 函数吗?

java - CompletableFuture.thenAccept 确实可以阻塞