开发者社区> 问答> 正文

内联回调函数

当你编写使用回调函数的代码的时候,担心很多小函数的扩张可能会弄乱程序控制流。 你希望找到某个方法来让代码看上去更像是一个普通的执行序列。

展开
收起
哦哦喔 2020-04-17 13:55:25 739 0
1 条回答
写回答
取消 提交回答
  • 通过使用生成器和协程可以使得回调函数内联在某个函数中。 为了演示说明,假设你有如下所示的一个执行某种计算任务然后调用一个回调函数的函数(参考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 语句外,其他地方并没有出现任何的回调函数(其实是在后台定义的)。
    
    2020-04-17 13:55:35
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载