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 objTrue来确认迭代器是迭代器(因此在定义上不可重复):
    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/

    10-12 17:43
    查看更多