On Sun, Nov 16, 2014 at 6:57 PM, Garrett Berg <googb...@gmail.com> wrote: > However, there are times when I want to do type checking, and the builtin > function isinstance is of great use. However, this function fails to be > satisfactory in returning whether the object is a valid iterator. The call > hasattr(obj, '__iter__') also fails because str and bytes types both have > that, and are rarely what you mean when you are asking if something is an > iterator (how often have you iterated over a string?)
But the correct answer is that str and bytes are both iterable. So what you're asking is not whether something's a valid iterator, but whether it is a non-string-iterable, which is a definitely different thing. And that's basically what your gist is doing, although there's a slight error in its docstring: you talk about "iterators", but you're actually looking for "iterables". In Python, an iterable is something which you can iterate over: calling iter() on it will return something (rather than raising TypeError), which means you can use it in a 'for' loop. An iterator is an iterable which, when you call iter() on it, returns *itself*. Normally, you get an iterator by calling iter() on something iterable, if that makes sense. For example: >>> iter([1,2,3,4]) <list_iterator object at 0x7f2908ec0978> >>> iter(_) <list_iterator object at 0x7f2908ec0978> >>> iter(range(10)) <range_iterator object at 0x7f2908f21db0> >>> iter(_) <range_iterator object at 0x7f2908f21db0> >>> iter(globals()) <dict_keyiterator object at 0x7f2908eb8f98> >>> iter(_) <dict_keyiterator object at 0x7f2908eb8f98> The list, range, and dict (as returned by globals()) are all iterable; the ...iterator objects are iterators. I suspect that your use-case is actually looking for iterables, not iterators, so the fix is simply a docs change. At that point, your function becomes 100% correct, and a perfectly idiomatic way to express "iterable that isn't one of these types". It doesn't need to be a builtin, though. Incidentally, if you're doing a lot of isinstance tests like this, you might want to look at the collections module, which has some 'base classes' which can be used like that. >>> isinstance([1,2,3],collections.Iterable) True ChrisA -- https://mail.python.org/mailman/listinfo/python-list