通过使用生成器和协程可以使得回调函数内联在某个函数中。 为了演示说明,假设你有如下所示的一个执行某种计算任务然后调用一个回调函数的函数(参考7.10小节):
def apply_async(func, args, , callback): # Compute the result result = func(args)
# Invoke the callback with the result
callback(result)
接下来让我们看一下下面的代码,它包含了一个 Async 类和一个 inlined_async 装饰器:
from queue import Queue from functools import wraps
class Async: def init(self, func, args): self.func = func self.args = args
def inlined_async(func): @wraps(func) def wrapper(args): f = func(args) result_queue = Queue() result_queue.put(None) while True: result = result_queue.get() try: a = f.send(result) apply_async(a.func, a.args, callback=result_queue.put) except StopIteration: break return wrapper 这两个代码片段允许你使用 yield 语句内联回调步骤。比如:
def add(x, y): return x + y
@inlined_async def test(): r = yield Async(add, (2, 3)) print(r) r = yield Async(add, ('hello', 'world')) print(r) for n in range(10): r = yield Async(add, (n, n)) print(r) print('Goodbye') 如果你调用 test() ,你会得到类似如下的输出:
5 helloworld 0 2 4 6 8 10 12 14 16 18 Goodbye 你会发现,除了那个特别的装饰器和 yield 语句外,其他地方并没有出现任何的回调函数(其实是在后台定义的)。