迭代器也是可迭代的吗?

15 python methods iterator iterable python-3.x

我找到:

>>> a={'x':42, 'y':3.14, 'z':7}
>>> b=a.__iter__()
>>> b.__dir__()
['__next__', ..., '__iter__', ...]
>>> b
<set_iterator object at 0x7efdd4e5afc0>
Run Code Online (Sandbox Code Playgroud)

迭代器是否总是有__iter__方法?

根据/sf/answers/691898161/,迭代器也是可迭代的.如果迭代器总是有__iter__方法是真的吗?

MSe*_*ert 11

迭代需要实现__iter__方法或__getitem__方法:

如果对象for实现__iter__()或者可以迭代对象__getitem__().

迭代器需要一个__iter__方法(返回self)和一个__next__方法(我不是100%肯定__next__).

迭代器总是有__iter__方法吗?

是!

这也在数据模型中记录:

object.__iter__(self)

当容器需要迭代器时,将调用此方法.此方法应返回一个新的迭代器对象,该对象可以迭代容器中的所有对象.对于映射,它应该迭代容器的键.

Iterator对象也需要实现此方法; 他们被要求归还自己.有关迭代器对象的更多信息,请参阅迭代器类型.

(强调我的)

至于你的第二个问题:

迭代器也是可迭代的吗?

是的,因为它有一个__iter__方法.

补充说明

除了正式的实现之外,只需检查是否iter()可以调用它就可以很容易地检查某些东西是否可迭代:

def is_iterable(something):
    try:
        iter(something)
    except TypeError:
        return False
    else:
        return True
Run Code Online (Sandbox Code Playgroud)

同样,可以通过检查iter()调用某些东西是否返回自身来检查某些东西是否为迭代器:

def is_iterator(something):
    try:
        return iter(something) is something  # it needs to return itself to be an iterator
    except TypeError:
        return False
Run Code Online (Sandbox Code Playgroud)

但是不要在开发代码中使用它们,这些只是用于"可视化".大多数情况下,你只是使用迭代器for ... in ...或者你需要使用迭代器iterator = iter(...),然后通过调用处理迭代器next(iterator)直到它抛出一个StopIteration.

  • @Ben:在Python 2中,`str`没有`__iter__`.我不知道任何内置的可迭代类型在Python 3上没有`__iter__`. (3认同)

Mos*_*oye 7

迭代器是可迭代的.是的,迭代器总是有一个__iter__方法.

调用iter迭代器来调用__iter__钩子,返回相同的迭代器:

>>> it = iter([]) # return iterator from iterable
>>> it is iter(iter(it)) is it.__iter__().__iter__().__iter__()
True
Run Code Online (Sandbox Code Playgroud)

方法链的经典例子.

正如您必须注意到的,自定义类的迭代器协议的大多数实现始终如下:

def __iter__(self):
    return self
Run Code Online (Sandbox Code Playgroud)

也就是说,如果迭代没有被委托给另一个迭代器,那就是说return iter(...).

如果迭代器没有实现迭代器协议,你会不会觉得这样反直觉?__iter__协议的实施描述如下:

iterator.__iter__()
Run Code Online (Sandbox Code Playgroud)

返回迭代器对象本身.这是允许容器和迭代器与forin语句一起使用所必需的.

[ 强调我的 ]

此行为预期与builtins返回的迭代器对象一致:

>>> m = map(None, [])
>>> m
<map object at 0x...>
>>> m is m.__iter__().__iter__().__iter__()
True
Run Code Online (Sandbox Code Playgroud)

PS:我为反复打电话而道歉; 让它看起来像是正确的事情.但事实并非如此!

  • 不,你在想"迭代"."迭代器"总是有一个`__iter__`方法. (2认同)