python - Detecting that an object is repeatedly iterable -


does obj == iter(obj) imply obj isn't repeatedly iterable , vice versa? didn't see such wording in docs, according this comment, standard library checks if object repeatedly iterable by testing if iter(obj) obj:

@agf: there parts of python standard library rely on part of spec; they detect whether iterator/generator testing if iter(obj) obj:, because true iterator/generator object have __iter__ defined identity function. if test true, convert list allow repeated iteration, otherwise, it's assumed object repeatably iterable, , can use is.
shadowranger jun 3 @ 17:23

the docs state if obj iterator, it's required iter(obj) returns obj. don't think that's enough conclude non-repeatedly iterable objects can identified using iter(obj) obj.

all iterators iterables, not iterables iterators.

the requirement of iterable defines __iter__() method returns iterator:

one method needs defined container objects provide iteration support:

container.__iter__()
return iterator object.

an iterator must follow iterator protocol, has 2 requirements:

  1. it has __iter__() method that returns object itself:

    iterator.__iter__()
    return iterator object itself.

  2. it has __next__() method returns next item on each call, and, once exhausted, raises stopiteration on every subsequent call:

    once iterator’s __next__() method raises stopiteration, must continue on subsequent calls. implementations not obey property deemed broken.

these requirements mean iterators never repeatable, , can confirm iterable iterator (and therefore unrepeatable definition) confirming iter(obj) obj true:

def is_unrepeatable(obj):     return iter(obj) obj 

however: since requirement of iterable iter(obj) returns some iterator, can't prove is repeatable. iterable define __iter__() method returns iterator different behaviour each time it's called: instance, return iterator iterates on elements first time it's called, on subsequent calls, return iterator raises stopiteration.

this behaviour strange (and annoying), not prohibited. here's example of non-repeatable iterable class not iterator:

class unrepeatable:      def __init__(self, iterable):         self.iterable = iterable         self.exhausted = false      def __iter__(self):         if self.exhausted:             return         else:             self.exhausted = true             yield self.iterable 

>>> x = unrepeatable([1,2,3]) >>> list(x) [1, 2, 3] >>> list(x) [] >>> iter(x) x false >>>  

i wouldn't hesitate call such "fake iterator" badly-behaved, , can't think of situation you'd find 1 in wild, demonstrated above, possible.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -