(注意:这个问题严格关于API的设计,而不是关于如何实现它;即我只关心我的API的客户端在这里看到的,而不是我所拥有的做它的工作。)
简单来说:我想知道Python中已建立的模式 - 如果有的话 - explicit futures(又名承诺,又称延期,又名任务 - 名称因框架而异)。以下是更详细的说明。
考虑一个像这样的简单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
方法,并使用stock IAsyncResult
接口来注册回调并传递结果值。在.NET 4+中,使用System.Threading.Tasks
,以便启用所有任务组合运算符(WhenAll
等),并连接到C#5.0 async
功能。
另一个例子,在JavaScript中,标准库中没有任何内容可以覆盖它,但是jQuery已经推广了现在为separately specified的“延迟承诺”界面。因此,如果我在JS中编写异步readLine
,我会将其命名为readLineAsync
,并对返回的值实现then
方法。
如果有的话,Python领域的既定模式是什么?通过标准库,我看到几个提供异步API的模块,但它们之间没有一致的模式,没有像“任务”或“承诺”的标准化协议。也许有一些模式可以从流行的第三方库中获得?
我也看到了Twisted中的(在此上下文中经常提及)Deferred类,但它似乎是一个通用的promise API过度设计,而是适应了这个库的特定需求。它看起来不像我可以轻松地克隆接口(不依赖于它们),这样如果客户端在他的应用程序中同时使用两个库,我们的promise将很好地互操作。是否有任何其他流行的库或框架具有明确设计的API,我可以复制(和互操作)而不需要直接依赖?
答案 0 :(得分:6)
好的,所以我找到了PEP-3148,它有一个Future
类。就我所知,我不能完全按原样使用它,因为正确的实例仅由Executor
创建,并且这是一个将现有的同步API转换为异步的类,例如:将同步调用移动到后台线程。但是,我可以完全复制Future
个对象提供的方法 - 它们与我期望的非常接近,即(阻塞)查询结果,取消和添加回调的能力。
这听起来像是一种合理的做法吗?或许它应该伴随着向Python标准库添加通用“未来”概念的抽象基类的提议,就像Python集合有ABCs一样。
答案 1 :(得分:1)
阅读各种“服务器”库以获取提示。
一个很好的例子是BaseHTTPServer
具体来说,HTTPServer类定义显示了如何提供“处理程序类”。
每个请求都实例化一个处理程序类的实例。然后该对象处理请求。
如果您想使用“回调”编写“异步I / O”,则需要为您的读者提供ReadHandler
课程。
class AsyncReadHandler( object ):
def input( self, line, server ):
print( line )
read_line_async( AsyncReadHandler )
这样的事情将遵循一些既定的设计模式。
答案 2 :(得分:0)
你看过decorators了吗?
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)