isIterable (was Re: FixedPoint)

John Machin sjmachin at lexicon.net
Fri Feb 8 18:15:06 EST 2002


Alex Martelli <aleax at aleax.it> wrote in message news:<GJS88.49612$3J1.1396553 at news2.tin.it>...
[snip]
> Unfortunately, if we're in Python 2.2 and x is an iterator, isIterable
> "consumes" x's first item.  This isn't hard to fix:
> 
> def isIterable(x):
>     try: x=iter(x)
>     except: pass
>     else: return 1
>     try:
>         for i in x: return 1   # iterable
>         else: return 1         # iterable, although empty
>     except:
>         return 0
> 
> This assumes function iter, if defined, is "sensible" -- it returns an
> iterator, or else raises an exception.  Builtin function iter does meet
> this requirement (it raises a TypeError if __iter__ is defined but
> returns a non-iterator), and (as usual in Python) it seems sensible
> to assume that if somebody has replaced a builtin function then that 
> somebody is responsible for the overall results still being sensible.

Ignoring the possibility that someone has implemented a botched
replacement for the builtin iter() function, I am having some
difficulty finding an example of an x that would raise an exception in
"iter(x)" but be acceptable in "for i in x:". All sorts of things that
I've tried either pass the first stage of your isIterable() or fail
both stages.

The 2.2 manual says about iter():
"""
Without a second argument, o must be a collection object which
supports the iteration protocol (the __iter__() method), or it must
support the sequence protocol (the __getitem__() method with integer
arguments starting at 0). If it does not support either of those
protocols, TypeError is raised.
"""

Looks to me like iter() is already doing what is in your second stage.

Can you supply an example which requires your second stage, please?



More information about the Python-list mailing list