Я пытаюсь обернуть голову вокруг asyncio
в Python.Я написал эту маленькую программу, которая при вызове будет сначала печатать
Загрузка с сервера
Делать вещи, называемые
, а затем через одну секунду
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()
Вот ссылка на работающую демонстрацию: https://repl.it/repls/PleasedHeavenlyLock