iter function包装列表或元组之类的对象,以便将它们用作迭代器,例如,可以使用next
。例如,
next(iter([1, 2, 3]))
返回1.
如果我们传递给iter
的对象已经是迭代器,那么内部会发生什么?它只是返回原始对象,即无操作?或者它是否会生成一个包装原始迭代器的新迭代器?通过包装我当然不是指复制原始迭代器。
答案 0 :(得分:3)
TLDNR:iter
返回obj.__iter_
。它不会返回obj
""。
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__
存在时,它就会返回。大多数(所有?)内置迭代器都有__iter__ = self
,例如
PyTypeObject PyListIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"listiterator", /* tp_name */
....
PyObject_SelfIter, /* tp_iter */
....
但对于userland对象来说,这不是必需的:
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
答案 1 :(得分:1)
经验证据很好,但是the docs are pretty explicit。
迭代器必须有一个
__iter__()
方法,它返回迭代器对象本身
如果使用__next__()
实现对象,则应该使用__iter__()
方法返回self
。打破这个规则意味着你有一个不是迭代器的对象,但看起来像是一个灾难的接收者。