obj == iter(obj)
是否暗示obj
不可重复迭代,反之亦然?我没有在文档中看到任何这样的措辞,但是根据this comment,标准库检查对象是否可重复迭代by testing if iter(obj) is obj
:
文档确实指出,如果obj
是迭代器,则要求iter(obj)
返回obj
。但是我不足以得出可以使用iter(obj) is obj
标识非重复的可迭代对象的结论。
最佳答案
所有迭代器都是可迭代的,但并非所有迭代器都是迭代器。
可迭代的唯一requirement是它定义了一个__iter__()
方法,该方法返回一个迭代器:
iterator必须遵循迭代器协议(protocol),该协议(protocol)有两个要求:
__iter__()
方法that returns the object itself:__next__()
方法,该方法会在每次调用时返回下一个项目,并且一旦耗尽,就会引发StopIteration
on every subsequent call:这些要求意味着迭代器永远不可重复,并且您始终可以通过确认
iter(obj) is obj
为True
来确认迭代器是迭代器(因此在定义上不可重复):def is_unrepeatable(obj):
return iter(obj) is obj
但是:因为唯一的要求是
iter(obj)
返回一些迭代器,所以您不能证明它是可重复的。一个可迭代的对象可以定义一个__iter__()
方法,该方法每次调用时都会返回具有不同行为的迭代器:例如,它可以返回一个迭代器,该迭代器在第一次被调用时在其元素上进行迭代,但是在后续调用中,返回一个立即引发StopIteration
的迭代器。这种行为会很奇怪(很烦人),但不是禁止的。这是一个不可重复的可迭代类的示例,该类不是迭代器:
class Unrepeatable:
def __init__(self, iterable):
self.iterable = iterable
self.exhausted = False
def __iter__(self):
if self.exhausted:
return
else:
self.exhausted = True
yield from self.iterable
>>> x = Unrepeatable([1,2,3])
>>> list(x)
[1, 2, 3]
>>> list(x)
[]
>>> iter(x) is x
False
>>>
我会毫不犹豫地称其为“虚假迭代器”,并且我想不出在野外找到一个这样的情况,但是如上所示,这是有可能的。
关于python - 检测到对象可重复迭代,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40445455/