如何创建可在创建后启动的懒惰Future in Python(asyncio)?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (46)

我试图asyncio用Python 来包围我的头。我写了这个小程序,当被调用时将首先打印

Server booting

Do stuff called

然后在一秒之后

Async Thingy

基本上,这模仿Server的是要建立一个PeerPool__init__依赖于ThingThatWeAreWaitingOn。我希望能够创造PeerPool__init__,并通过一个Awaitable[ThingThatWeAreWaitingOn]使PeerPool能尽快使用,因为它已准备就绪。再说一次,这似乎工作得很好,但是现在我们已经开始了ThingThatWeAreWaitingOn直接从内部解决的任务,__init__但理想情况下我希望能够从内部开始解决问题run()

我会怎么做?

import asyncio
from typing import (
    Awaitable,
    Any
)

class ThingThatWeAreWaitingOn():
    name = "Async Thingy"

class PeerPool():

    def __init__(self, discovery: Awaitable[ThingThatWeAreWaitingOn]):
        self.awaitable_discovery = discovery

    def do_stuff(self):
        print("Do stuff called")
        self.awaitable_discovery.add_done_callback(lambda d: print(d.result().name))

class Server():

    def __init__(self):
        # This immediately kicks of the async task but all I want is to 
        # create a Future to pass that would ideally be kicked off in
        # the run() method
        self.fut_discovery = asyncio.ensure_future(self.get_discovery())
        self.peer_pool = PeerPool(self.fut_discovery)

    async def get_discovery(self):
        await asyncio.sleep(1)
        return ThingThatWeAreWaitingOn()

    def run(self):
        loop = asyncio.get_event_loop()
        print("Server booting")

        # Here is where I want to "kick off" the self.fut_discovery but how?
        # self.fut_discovery.kick_off_now()

        self.peer_pool.do_stuff()

        loop.run_forever()

server = Server()
server.run()
提问于
用户回答回答于
class Server():    
    def __init__(self):
        self.fut_discovery = asyncio.Future()
        self.peer_pool = PeerPool(self.fut_discovery)

    async def get_discovery(self):
        await asyncio.sleep(1)
        return ThingThatWeAreWaitingOn()

    def run(self):
        loop = asyncio.get_event_loop()
        print("Server booting")

        async def discovery_done():
            res = await self.get_discovery()
            self.fut_discovery.set_result(res)
        asyncio.ensure_future(discovery_done())  # kick discovery to be done

        self.peer_pool.do_stuff()
        loop.run_forever()

class PeerPool():
    def __init__(self, fut_discovery: asyncio.Future):

扫码关注云+社区

领取腾讯云代金券