在 Python 中的现有迭代器上使用 iter:迭代器会发生什么情况?
Using iter on an existing iterator in Python: What happens to the iterator?
iter function 包装列表或元组等对象,以便将它们用作迭代器,例如,可以使用 next
。例如,
next(iter([1, 2, 3]))
returns 1.
如果我们传递给 iter
的对象已经是一个迭代器,内部会发生什么?它只是 return 原始对象,即无操作吗?或者它会产生一个新的迭代器来包装原来的迭代器吗?当然,包装并不是指复制原始迭代器。
TLDNR:iter
returns obj.__iter_
。它没有 return obj
"as is".
iter
的 Cpython 实现非常简单:
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
因此,当您调用 iter(obj)
并且 obj.__iter__
存在时,它只是 return。大多数(全部?)内置迭代器有 __iter__ = self
,例如
PyTypeObject PyListIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"listiterator", /* tp_name */
....
PyObject_SelfIter, /* tp_iter */
....
但这对于用户空间对象来说不是必需的:
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
经验证据很好,但是 the docs are pretty explicit。
Iterators are required to have an __iter__()
method that returns the iterator object itself
如果您使用 __next__()
实现一个对象,您应该有一个 returns self
的 __iter__()
方法。违反这条规则意味着你有一个不是迭代器但看起来像迭代器的对象,这是灾难的接收者。
iter function 包装列表或元组等对象,以便将它们用作迭代器,例如,可以使用 next
。例如,
next(iter([1, 2, 3]))
returns 1.
如果我们传递给 iter
的对象已经是一个迭代器,内部会发生什么?它只是 return 原始对象,即无操作吗?或者它会产生一个新的迭代器来包装原来的迭代器吗?当然,包装并不是指复制原始迭代器。
TLDNR:iter
returns obj.__iter_
。它没有 return obj
"as is".
iter
的 Cpython 实现非常简单:
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
因此,当您调用 iter(obj)
并且 obj.__iter__
存在时,它只是 return。大多数(全部?)内置迭代器有 __iter__ = self
,例如
PyTypeObject PyListIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"listiterator", /* tp_name */
....
PyObject_SelfIter, /* tp_iter */
....
但这对于用户空间对象来说不是必需的:
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
经验证据很好,但是 the docs are pretty explicit。
Iterators are required to have an
__iter__()
method that returns the iterator object itself
如果您使用 __next__()
实现一个对象,您应该有一个 returns self
的 __iter__()
方法。违反这条规则意味着你有一个不是迭代器但看起来像迭代器的对象,这是灾难的接收者。