【发布时间】:2019-11-24 15:33:36
【问题描述】:
我一直在尝试理解异步编程,尤其是在 Python 中。我知道 asyncio 是建立在一个调度协程执行的事件循环之上的,但是我已经阅读了几种不同的方式来定义协程,我很困惑它们是如何相互关联的。
我阅读了this article 以了解有关该主题的更多背景信息。尽管它涵盖了我提到的四种类型的协程中的每一种,但它并没有完全描述它们之间的区别。无需任何外部模块,可以使用yield作为等号右侧的表达式创建协程,然后可以通过.send()输入数据。但是,使用@asyncio.coroutine 和@types.coroutine 装饰器的代码示例从不使用我发现的.send()。文章中的代码示例如下:
# Coroutine using yield as an expression
def coro():
hello = yield "Hello"
yield hello
c = coro()
print(next(c), end=" ")
print(c.send("World")) # Outputs Hello World
# Asyncio generator-based coroutine
@asyncio.coroutine
def display_date(num, loop):
end_time = loop.time() + 50.0
while True:
print("Loop: {} Time: {}".format(num, datetime.datetime.now()))
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(random.randint(0, 5))
# Types generator-based coroutine
@types.coroutine
def my_sleep_func():
yield from asyncio.sleep(random.randint(0, 5))
# Native coroutine in Python 3.5+
async def display_date(num, loop, ):
end_time = loop.time() + 50.0
while True:
print("Loop: {} Time: {}".format(num, datetime.datetime.now()))
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(random.randint(0, 5))
我的问题是:
-
yield协程与types或asyncio修饰的协程有什么关系,.send()功能在哪里使用? - 装饰器为未装饰的基于生成器的协程添加了哪些功能?
-
@asyncio.coroutine和@types.coroutine装饰器有何不同?我阅读this answer 试图理解这一点,但这里提到的唯一区别是types协程在没有yield 语句的情况下像子程序一样执行。还有什么其他的吗? - 这些基于生成器的协程在功能和实现上与最新的原生
async/await协程有何不同?
【问题讨论】:
-
yield 旨在将值 out 发送到使用您的生成器的任何人。发送回生成器的内容完全取决于处理生成器的代码。在协程的情况下,您的生成器由某种事件循环处理(它为您调用 .send),并且您可以保证传递给生成器的值是直接从您传递的值产生的,因此为什么“ “等待”是协程的一个更直观的词。
-
@TadhgMcDonald-Jensen asyncio.coroutine 和 types.coroutine 装饰器在用途和功能上有何不同?
-
我真的不知道是什么原因我没有发布答案,我会看看源代码,看看我是否能找到适合你的答案。
-
在此处查看
@asyncio.coroutine和@types.coroutine之间的重要区别:stackoverflow.com/a/49477233/2085626
标签: python asynchronous async-await generator coroutine