if iter(iterator) is iterator

Steve D'Aprano steve+python at pearwood.info
Sun Nov 13 19:40:18 EST 2016


On Mon, 14 Nov 2016 07:02 am, Antoon Pardon wrote:

> 
> Some time ago I read a text or saw a video on iterators and one thing
> I remember from it, is that you should do something like the following
> when working with iterators, to avoid some pitt falls.
> 
> def bar(iterator):
>     if iter(iterator) is iterator:
>         ...
> 
> However I can't relocate it and can't remember the what and how anymore.
> Does anyone know what this is about?

Probably something like this:


def function(iterable):
    if iter(iterable) is iterable:
        print("iterable is already an iterator")
        assert hasattr(iterable, '__next__')  # 'next' in Python 2
    else:
        print("iterable is not an iterator")
        print("it may be a list, dict, string, etc.")


`iter(thing) is thing` is an easy way to check whether thing is an iterator.

I'm surprised that the inspect module doesn't appear to have isiterable and
isiterator functions. Here's my first attempt at both:


def isiterable(obj):
    """Return True if obj is an iterable, and False otherwise.

    Iterable objects can be iterated over, and they provide either
    an __iter__ method or a __getitem__ method.

    Iteration over an object tries calling the object's __iter__ 
    method (if any), then repeatedly calls __next__ on the result
    until a StopIteration exception is raised (the Iterator
    Protocol). Otherwise, it tries calling __getitem__ with 
    arguments 0, 1, 2, 3 ... until an IndexError exception is
    raised (the Sequence Protocol).
    
    """
    T = type(obj)
    return hasattr(T, '__iter__') or hasattr(T, '__getitem__')


def isiterator(obj):
    """Return True if obj is an iterator, and False otherwise.

    Iterators can be iterated over, and they provide the following
    methods:

    - __iter__ which returns itself
    - __next__

    Iteration over an iterator repeatedly calls __next__ until a
    StopIteration exception is raised.
    """
    T = type(obj)
    if hasattr(T, '__iter__') and hasattr(T, '__next__'):
        return iter(obj) is obj
    return False






-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list