代码之家  ›  专栏  ›  技术社区  ›  VPfB

如何在等待的子类中使用super()?

  •  7
  • VPfB  · 技术社区  · 7 年前

    让我们从一个非常简单的基类开始创建对象,在短暂的睡眠后异步返回99。子类应该只向结果中添加+1。

    super() 指基类。

    import asyncio
    
    class R99:
        def __await__(self):
            loop = asyncio.get_event_loop()
            fut = loop.create_future()
            loop.call_later(0.5, fut.set_result, 99)
            return fut.__await__()
    
    class R100(R99):
        async def add1(self):
            v = await R99()
            #v = await super().__await__()   # <== error
            return v + 1
    
        def __await__(self):
            return self.add1().__await__()
    
    async def test():
        print(await R99())
        print(await R100())
    
    asyncio.get_event_loop().run_until_complete(test())
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   Vincent    7 年前

    这个 await method 必须返回一个迭代器,这样就可以将其作为生成器并使用 yield from 语法:

    class R100(R99):
    
        def __await__(self):
            v = yield from super().__await__()
            return v + 1
    
        2
  •  2
  •   user4815162342    7 年前

    如果允许修改 R99 __await__() 调用一个实际的协同程序,它可以链接到 super() 以常规方式:

    import asyncio
    
    class R99:
        async def await_coro(self):
            loop = asyncio.get_event_loop()
            fut = loop.create_future()
            loop.call_later(0.5, fut.set_result, 99)
            return await fut
    
        def __await__(self):
            return self.await_coro().__await__()
    
    class R100(R99):
        async def await_coro(self):
            v = await super().await_coro()
            return v + 1
    

    如果这不是一个选择,@文森特的回答准确地解释了如何从一个链接 __await__ 另一个。请注意,你的想法是非常正确的 await 是新的吗 yield from -是的,通常没有理由使用 在新编写的异步代码中(这当然不适用于委托给子生成器的非异步相关生成器;欢迎继续使用 .)

    __等待\() yield 挂起协同程序,将控制权返回到事件循环,然后 收益率 委托给另一个实现协同程序的生成器。在新代码中,该层的唯一有效目的是实现一个可等待的对象,而不使用解释器,例如在Python/C或Cython中。这是通过提供 __等待__ 返回一个迭代器,如图所示 here . 结果对象相当于 async def .