我正在试着用Python语言理解asyncio
。我写了这个小程序,当调用它时,它将首先打印
服务器引导
做一些叫做
然后在一秒钟之后
异步事物
这正是它应该做的,但这还不是我想要的方式。
基本上,这模拟了一个Server
,它想要在依赖于ThingThatWeAreWaitingOn
的__init__
中创建一个PeerPool
。我希望能够在__init__
中创建PeerPool
,并在准备就绪时传递PeerPool
可以使用的Awaitable[ThingThatWeAreWaitingOn]
。同样,这似乎工作得很好,但问题是,根据现在的代码,我们直接从__init__
内部开始解析ThingThatWeAreWaitingOn
的任务,但理想情况下,我希望能够从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
发布于 2018-06-08 07:22:11
如果我没理解错的话,你想要这样的东西:
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,以使其对象类似于未来/可等待。
https://stackoverflow.com/questions/50750938
复制相似问题