Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #80862 > unrolled thread
| Started by | Chris Angelico <rosuav@gmail.com> |
|---|---|
| First post | 2014-11-16 19:14 +1100 |
| Last post | 2014-11-16 19:14 +1100 |
| Articles | 1 — 1 participant |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: isiter builtin Chris Angelico <rosuav@gmail.com> - 2014-11-16 19:14 +1100
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-11-16 19:14 +1100 |
| Subject | Re: isiter builtin |
| Message-ID | <mailman.15875.1416125654.18130.python-list@python.org> |
On Sun, Nov 16, 2014 at 6:57 PM, Garrett Berg <googberg@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
Back to top | Article view | comp.lang.python
csiph-web