什么样的对象“屈服于”可以与之一起使用?

2024-06-14 20:26:55 发布

您现在位置:Python中文网/ 问答频道 /正文

最初(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形式的参数


Tags: 对象方法fromself类型def语法例程
1条回答
网友
1楼 · 发布于 2024-06-14 20:26:55

您可以检查CPython evaluates that statement的性能。由此可知,它需要是一个协同程序或一个iterable:

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();
}

相关问题 更多 >