if iter(iterator) is iterator

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Nov 13 23:54:26 EST 2016


On Monday 14 November 2016 11:59, Chris Angelico wrote:

> On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
> <steve+python at pearwood.info> wrote:
>> 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__')
> 
> Any particular reason to write it that way, rather than:
> 
> def isiterable(obj):
>     try:
>         iter(obj)
>         return True
>     except TypeError:
>         return False


class BadIterable:
    def __iter__(self):
        self.launch_missiles()
        return self


In general, merely testing whether something is a certain kind of thing 
shouldn't actually run that thing's code.

(That's not always possible. E.g. the thing's metaclass might launch missiles 
when you check for the existence of an attribute. But reducing the vulnerable 
surface as much as possible is a good thing.)



-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!




More information about the Python-list mailing list