12

(注意:这个问题严格来说是关于 API 的设计,而不是关于如何实现它;即我只关心我的 API 的客户端在这里看到了什么,而不是我必须做什么才能使其工作。)

简单来说:我想知道 Python 中明确的未来(又名承诺,又名延迟,又名任务 - 名称因框架而异)的已建立模式 - 如果有的话。以下是更详细的描述。

考虑一个简单的 Python API,如下所示:

def read_line():
   ...
s = read_line()
print(s)

这是一个同步版本 - 如果线路尚不可用,它将阻塞。现在假设我想提供一个相应的异步(非阻塞)版本,它允许注册一个回调,以便在操作完成后调用。例如,一个简单的版本可能如下所示:

def read_line_async(callback):
   ...
read_line_async(lambda s: print(s))

现在,在其他语言和框架中,这些 API 通常存在现有的强制或至少是完善的模式。例如,在版本 4 之前的 .NET 中,通常会提供一对BeginReadLine/EndReadLine方法,并使用 stockIAsyncResult接口来注册回调并传递结果值。在 .NET 4+ 中,使用System.Threading.Tasks, 以启用所有任务组合运算符(WhenAll等),并与 C# 5.0async功能挂钩。

再举一个例子,在 JavaScript 中,标准库中没有什么可以涵盖这一点,但 jQuery 已经普及了现在单独指定的“延迟承诺”接口。因此,如果我要在 JS 中编写 async readLine,我会命名它,并在返回值上readLineAsync实现方法。then

Python 领域的既定模式(如果有的话)是什么?查看标准库,我看到几个提供异步 API 的模块,但它们之间没有一致的模式,也没有像“任务”或“承诺”的标准化协议。也许有一些模式可以从流行的第三方库中派生出来?

我还在 Twisted 中看到了(在这种情况下经常提到的)Deferred类,但它似乎针对通用的 Promise API 进行了过度设计,而是适应了该库的特定需求。它看起来不像是我可以轻松克隆一个接口(而不依赖于它们)的东西,这样如果客户在他的应用程序中同时使用这两个库,我们的 Promise 就可以很好地互操作。是否有任何其他流行的库或框架具有为此明确设计的 API,我可以在不直接依赖的情况下复制(并与之互操作)?

4

3 回答 3

6

好的,所以我找到了PEP-3148,它确实有一个Future类。就我所见,我不能完全按原样使用它,因为正确的实例仅由Executor, 创建,这是一个通过例如将同步调用移动到后台线程来将现有同步 API 转换为异步的类。但是,我可以完全复制Future对象提供的方法——它们非常符合我的预期,即(阻止)查询结果、取消和添加回调的能力。

这听起来像一个合理的方法吗?也许,它是否应该伴随一个提议,为 Python 标准库中的通用“未来”概念添加一个抽象基类,就像 Python 集合有它们的ABC一样。

于 2011-09-02T04:26:04.413 回答
1

阅读各种“服务器”库以获取提示。

一个很好的例子是BaseHTTPServer

具体来说,HTTPServer类定义显示了如何提供“处理程序类”。

每个请求都会实例化处理程序类的一个实例。然后该对象处理请求。

如果您想编写带有“回调”的“异步 I/O”,您需要ReadHandler为您的读者提供一个类。

class AsyncReadHandler( object ):
    def input( self, line, server ):
        print( line )

read_line_async( AsyncReadHandler )

类似的东西会遵循一些既定的设计模式。

于 2011-09-02T02:14:37.133 回答
0

你看过装饰器吗?

from threading import Thread

def addCallback(function):
    def result(parameters,callback):
        # Run the function.
        result = function(parameters)
        # Run the callback asynchronously.
        Thread(target=callback).start()
        # Run the callback synchronously.
        #callback()
        # Return the value of the function.
        return result
    return result

@ addCallback
def echo(value):
    print value

def callback():
    print 'Callback'

echo('Hello World!',callback)
于 2011-09-02T04:52:54.287 回答