【发布时间】:2020-09-06 21:40:34
【问题描述】:
最初 (PEP 380),yield from 语法被引入用于委托给“子生成器”。后来它与现在 deprecated 基于生成器的协程一起使用。
我不知道yield from 一般可以应用于什么样的对象。我的第一个猜想是它只需要对象上的__iter__ 方法来返回一个迭代器。事实上,以下内容适用于 Python 3.8:
class C:
def __init__(self, n):
self.n = n
def __iter__(self):
return iter(range(self.n))
def g(n):
yield from C(n)
print(tuple(g(3)))
但是,它也适用于一些等待对象,例如 asyncio.sleep(1),它们没有 __iter__ 方法。
一般规则是什么?什么决定了一个对象是否可以作为yield from 表单的参数?
【问题讨论】:
-
您走在正确的道路上,但也许
yield from asyncio.sleep(1)让您感到困惑。yield from是 Python 3.4 的语法等价于 Python 3.5await。查看 Python 3.4 asyncio: 18.5.9.3. Concurrency and multithreading 的文档。 -
@Felipe,你的意思是
yield from有两个完全不相关的意思吗?它只有两个,还是更多?在我给出的代码示例中,您不能将yield from替换为await,因此它们并不总是等价的。 -
@Felipe,我看不到您指出我的问题的文档在哪里得到了回答。
-
上面链接文档的第一段。 “一个事件循环在一个线程中运行,并在同一个线程中执行所有回调和任务。当一个任务在事件循环中运行时,没有其他任务在同一个线程中运行。但是当任务使用
yield from时,该任务被挂起,事件循环执行下一个任务。” -
异步编程在 Python 中是一个完全不同的概念(不同于生成器)。在当今世界,您使用关键字
await来利用异步函数,但在 3.4 之前,您将使用yield from而不是await(这就是为什么您可能会看到yield from散布在不支持异步函数的代码中似乎有发电机)。
标签: python python-3.x generator coroutine yield-from