在Python中的现有迭代器上使用iter:迭代器会发生什么?

SmC*_*lar 5 python iterator

国际热核实验堆函数封装像列表或元组对象,以便将它们作为迭代器,即一个能够使用next,例如。例如,

next(iter([1, 2, 3]))
Run Code Online (Sandbox Code Playgroud)

返回1。

如果我们传递给的对象iter已经是迭代器,内部会发生什么?它是否只是返回原始对象,即无操作?还是产生一个包装原始迭代器的新迭代器?当然,包装并不是指复制原始的迭代器。

geo*_*org 3

TLDNR:iter返回obj.__iter_。它不会obj“按原样”返回。

Cpython 的实现iter非常简单:

PyObject *
PyObject_GetIter(PyObject *o)
{
    PyTypeObject *t = o->ob_type;
    getiterfunc f = NULL;
    if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
        f = t->tp_iter; // <- if it has __iter__, return that
    ....more stuff
Run Code Online (Sandbox Code Playgroud)

因此,当您调用iter(obj)obj.__iter__存在时,它只会返回该值。大多数(全部?)内置迭代器都有__iter__ = self,例如

PyTypeObject PyListIter_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "listiterator",                             /* tp_name */
    ....
    PyObject_SelfIter,                          /* tp_iter */
    ....
Run Code Online (Sandbox Code Playgroud)

但这对于用户态对象来说不一定是这样:

class X:
    def __iter__(self):
        return Y()

class Y:
    def __iter__(self):
        return iter('xyz')


a = iter(X())
b = iter(a)
print a is b # False
Run Code Online (Sandbox Code Playgroud)