我正试着用Python包围asyncio
。我写了这个小程序,在调用时将首先打印
服务器启动
做一些叫做
的事情
然后一秒后
Async Thingy
这正是应该做的,但它还不是我想要的方式。
基本上,这会模仿Server
想要在PeerPool
中创建__init__
的{{1}},这取决于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()
内部开始。
我该怎么做?
character
以下是可运行演示的链接:https://repl.it/repls/PleasedHeavenlyLock
答案 0 :(得分:2)
如果我理解一切正确,你需要这样的东西:
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()
您可能希望以某种方式重写代码以使其更清晰。现在,你不清楚你将要做什么以及哪部分代码取决于哪些。
例如,awaitable_discovery
名称具有误导性:明确等待不需要add_done_callback
方法。如果您正计划使用此方法,请签名
class PeerPool():
def __init__(self, fut_discovery: asyncio.Future):
会更有意义。
可能你应该为发现创建一个类。您可以继承asyncio.Future
或实施__await__
magic method,使其对象具有类似未来/等待的目标。