[英]Asyncio python: How to call object methods in coroutines?
我目前正在尝试做这样的事情:
import asyncio
class Dummy:
def method(self):
return 1
def __str__(self):
return "THIS IS A DUMMY CLASS"
async def start_doing():
asyncio.sleep(1)
return Dummy
async def do_something():
return start_doing().method()
async def main():
a = asyncio.create_task(do_something())
b = asyncio.create_task(do_something())
results = await asyncio.gather(a, b)
print(results)
asyncio.run(main())
但我得到这个错误:
AttributeError: 'coroutine' object has no attribute 'method'
这表明我无法在协程 object 上调用我的方法。 解决此问题的一种方法是执行以下操作:
async def do_something():
return (await start_doing()).method()
但我认为通过这样做,您本质上就是使您的代码同步。 您不是在生成未来,而是在do_something
中等待您的工作完成,然后继续执行队列中的下一个项目。
当awaitable
已等待并且我的 object 已准备好时,将来我应该如何调用 object 方法? 如何安排它在未来被调用?
等待调用,然后在返回的 class 的实例上调用该方法。
async def start_doing():
await asyncio.sleep(1)
return Dummy
async def do_something():
thing = await start_doing()
return thing().method()
当 awaitable 已等待并且我的 object 已准备好时,将来我应该如何调用 object 方法? 如何安排它在未来被调用?
看看我能不能把这个弄对。
do_something
时,它会被安排。do_something
开始。do_something
调用start_doing
并等待它。do_something
正在等待时,事件循环会从它那里拿走控制权并让其他东西轮流。start_doing
被安排,开始,完成等待/睡眠,返回 object
do_something
完成等待之后,事件循环将控制/焦点返回给它。
我真的不知道调度算法是什么,我认为它是一个循环事件,但它可能比这更智能。
要进一步扩展@wwii的答案并解决对使用await
阻塞风险的担忧,您可以使用以下f
之类的功能:
import time
from datetime import datetime
import asyncio
start = datetime.now()
async def f(x, block_for=3):
print(f"{x} IN {ellapsed_time()}s")
time.sleep(block_for)
print(f"{x} AWAIT {ellapsed_time()}s")
await asyncio.sleep(x)
print(f"{x} OUT {ellapsed_time()}s")
def ellapsed_time():
return (datetime.now() - start).seconds
asyncio.create_task(f(2))
asyncio.create_task(f(1))
产生:
2 IN 0s
2 AWAIT 3s
1 IN 3s
1 AWAIT 6s
2 OUT 6s
1 OUT 7s
在调用await
之前, f(2)
处于阻塞状态(防止任何其他任务被调度)。 一旦我们调用await
,我们就明确地通知调度程序我们正在等待某些东西(通常是 I/O,但这里只是“睡眠” )。 类似地, f(1)
阻止f(2)
出去,直到它调用await
。
如果我们移除阻塞部分(0s 的阻塞), f(1)
将被重新安排在f(2)
之前执行,因此将首先完成:
>>> start = datetime.now()
>>> asyncio.create_task(f(2, block_for=0))
>>> asyncio.create_task(f(1, block_for=0))
2 IN 0s
2 AWAIT 0s
1 IN 0s
1 AWAIT 0s
1 OUT 1s
2 OUT 2s
最后,关于这部分:
......如何安排它在未来被调用?
你可以看看python 中的 asyncio.sleep() 是如何实现的? ,它可能会帮助您更好地理解异步编程是如何工作的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.