python - `yield from` 可以与什么样的对象一起使用?

标签 python python-3.x generator coroutine yield-from

最初(PEP 380),yield from引入语法以用于委托(delegate)给“子生成器”。后来和现在一起使用 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 的参数给出形式?

最佳答案

您可以查看 CPython evaluates that statement .由此可见,它需要是协程或可迭代的:

case TARGET(GET_YIELD_FROM_ITER): {
    /* before: [obj]; after [getiter(obj)] */
    PyObject *iterable = TOP();
    PyObject *iter;
    if (PyCoro_CheckExact(iterable)) {
        /* `iterable` is a coroutine */
        if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
            /* and it is used in a 'yield from' expression of a
               regular generator. */
            Py_DECREF(iterable);
            SET_TOP(NULL);
            _PyErr_SetString(tstate, PyExc_TypeError,
                             "cannot 'yield from' a coroutine object "
                             "in a non-coroutine generator");
            goto error;
        }
    }
    else if (!PyGen_CheckExact(iterable)) {
        /* `iterable` is not a generator. */
        iter = PyObject_GetIter(iterable);
        Py_DECREF(iterable);
        SET_TOP(iter);
        if (iter == NULL)
            goto error;
    }
    PREDICT(LOAD_CONST);
    DISPATCH();
}

关于python - `yield from` 可以与什么样的对象一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61914515/

相关文章:

python - 尝试使用 super().__init__ 时出错

python - 从导入的模块线程初始化类变量在 Python 中是安全的吗?

python - 为什么变量的类型提示不作为函数参数的类型提示处理?

python - 从函数返回生成器

python - 如何解决 Numba 降低错误?

python - 幂律数据拟合不正确

python - #!/usr/bin/python3 shebang 的目的

python-3.x - 如何优化此 python 代码以对大输入进行排序?

javascript - NBA 选秀乐透在单击按钮后显示数组项目后将其删除

Python:使用filter()生成素数列表的代码中生成器和过滤器如何工作