gpt4 book ai didi

python - Python 协程可以不用 await 或 yield 实现吗?

转载 作者:行者123 更新时间:2023-11-28 18:02:48 24 4
gpt4 key购买 nike

我正在学习 Python await/async 语法,想知道如何在没有 async、await 或 yield 的情况下实现协程。例如,我使用 async def 语法制作了这个简单的三秒计时器:

import asyncio

async def coroutine():
count = 0
while count < 3:
count += 1
print(count)
await asyncio.sleep(1)

loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
loop.close()

结果:

1
2
3

我注意到我们可以通过实现 __await__ ( https://docs.python.org/3.6/reference/datamodel.html#awaitable-objects ) 来实现协程对象。这样我就可以成功删除 await

import asyncio

class Generator():
def __await__(self):
count = 0
while count < 3:
count += 1
print(count)
yield from asyncio.sleep(1)

loop = asyncio.get_event_loop()
loop.run_until_complete(Generator())
loop.close()

最后,我想像这样实现没有 yield 的迭代器:

import asyncio

class Iterator():

def __init__(self):
self.count = 0

def __iter__(self): return self

def __await__(self): return self

def __next__(self):
if self.count < 3:
self.count += 1
print(self.count)
return next(asyncio.sleep(1))
else:
raise StopIteration()

loop = asyncio.get_event_loop()
result = loop.run_until_complete(Iterator())
loop.close()

但是没有用。显示“1”后停止。

我知道这没有任何实用值(value),但我想知道它以正确理解 asyncio。我可以在没有 await 或 yield 的情况下实现协程吗?如果是这样怎么办?我用 Python 3.6.7 测试了它。

最佳答案

虽然协程是使用生成器实现的,但协程不是生成器:

import asyncio
from typing import Generator


def gen():
yield 1


async def coro():
pass


print(isinstance(gen(), Generator)) # True
print(isinstance(coro(), Generator)) # False

这是有意为之的,因为生成器只不过是协程的实现细节。迭代器也是如此:协程不是迭代器。

loop.run_until_complete 期望收到一些可等待的东西,比如 asyncio 协程或 future 。您正在尝试传递迭代器 - 具有不同行为的不同对象。


长话短说,如果你想实现兼容asyncio的协程:

  • 使用async def定义函数
  • 或者实现__await__魔法方法

并阅读 asyncio doc例如。

如果你想了解协同程序如何在非常低的层次上工作的一般概念,你可以关注这个 excellent video David Beazley 从头开始​​实现协程和事件循环。

关于python - Python 协程可以不用 await 或 yield 实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55039539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com