Ale*_*xey 6 python generator coroutine python-3.x yield-from
最初(PEP 380),yield from引入了语法以用于委托给“子生成器”。后来它与现在已弃用的基于生成器的协程一起使用。
我不知道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)))
Run Code Online (Sandbox Code Playgroud)
但是,它也适用于一些asyncio.sleep(1)没有__iter__方法的等待对象,例如。
一般规则是什么?是什么决定了一个对象是否可以作为yield fromform的参数给出?
您可以检查 CPython 如何计算该语句。由此可见,它必须是协程或可迭代的:
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |