I think the point of confusion here is that, although implementing __getitem__ does allow you to iterate over an object, it isn't part of the interface defined by Iterable.

The abstract base classes allow a form of virtual subclassing, where classes that implement the specified methods (in the case of Iterable, only __iter__) are considered by isinstance and issubclass to be subclasses of the ABCs even if they don't explicitly inherit from them. It doesn't check whether the method implementation actually works, though, just whether or not it's provided.

For more information, see PEP-3119, which introduced ABCs.


using isinstance(e, collections.Iterable) is the most pythonic way to check if an object is iterable

I disagree; I would use duck-typing and just attempt to iterate over the object. If the object isn't iterable a TypeError will be raised, which you can catch in your function if you want to deal with non-iterable inputs, or allow to percolate up to the caller if not. This completely side-steps how the object has decided to implement iteration, and just finds out whether or not it does at the most appropriate time.

As the ABC documentation mentions:

Checking isinstance(obj, Iterable) detects classes that are registered as Iterable or that have an __iter__() method, but it does not detect classes that iterate with the __getitem__() method. The only reliable way to determine whether an object is iterable is to call iter(obj).


To add a little more, I think the docs you've quoted are slightly misleading. To quote the iter docs, which perhaps clear this up:

object 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).

This makes it clear that, although both protocols make the object iterable, only one is the actual "iteration protocol", and it is this that isinstance(thing, Iterable) tests for. Therefore we could conclude that one way to check for "things you can iterate over" in the most general case would be:

isinstance(thing, (Iterable, Sequence))

However, this doesn't work because:

  1. your class doesn't implement __len__ (and doesn't need to anyway, being iterable only requires a sequence-compatible __getitem__); and

  2. Sequence is a complex interface:

    Complex interfaces do not support [virtual subclassing] because an interface is more than just the presence of method names. Interfaces specify semantics and relationships between methods that cannot be inferred solely from the presence of specific method names.

    so even a class that implements both __getitem__ and __len__ doesn't automatically become a Sequence, it needs to explicitly extend the ABC (at which point it would inherit an __iter__ implementation and become Iterable anyway).

Answer from jonrsharpe on Stack Overflow
🌐
Python Like You Mean It
pythonlikeyoumeanit.com › Module2_EssentialsOfPython › Iterables.html
Iterables — Python Like You Mean It
We will also encounter important non-sequential collections, like dictionaries and sets; these are iterables as well. It is also possible to have an iterable that “generates” each one of its members upon iteration - meaning that it doesn’t ever store all of its members in memory at once.
Top answer
1 of 3
9

I think the point of confusion here is that, although implementing __getitem__ does allow you to iterate over an object, it isn't part of the interface defined by Iterable.

The abstract base classes allow a form of virtual subclassing, where classes that implement the specified methods (in the case of Iterable, only __iter__) are considered by isinstance and issubclass to be subclasses of the ABCs even if they don't explicitly inherit from them. It doesn't check whether the method implementation actually works, though, just whether or not it's provided.

For more information, see PEP-3119, which introduced ABCs.


using isinstance(e, collections.Iterable) is the most pythonic way to check if an object is iterable

I disagree; I would use duck-typing and just attempt to iterate over the object. If the object isn't iterable a TypeError will be raised, which you can catch in your function if you want to deal with non-iterable inputs, or allow to percolate up to the caller if not. This completely side-steps how the object has decided to implement iteration, and just finds out whether or not it does at the most appropriate time.

As the ABC documentation mentions:

Checking isinstance(obj, Iterable) detects classes that are registered as Iterable or that have an __iter__() method, but it does not detect classes that iterate with the __getitem__() method. The only reliable way to determine whether an object is iterable is to call iter(obj).


To add a little more, I think the docs you've quoted are slightly misleading. To quote the iter docs, which perhaps clear this up:

object 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).

This makes it clear that, although both protocols make the object iterable, only one is the actual "iteration protocol", and it is this that isinstance(thing, Iterable) tests for. Therefore we could conclude that one way to check for "things you can iterate over" in the most general case would be:

isinstance(thing, (Iterable, Sequence))

However, this doesn't work because:

  1. your class doesn't implement __len__ (and doesn't need to anyway, being iterable only requires a sequence-compatible __getitem__); and

  2. Sequence is a complex interface:

    Complex interfaces do not support [virtual subclassing] because an interface is more than just the presence of method names. Interfaces specify semantics and relationships between methods that cannot be inferred solely from the presence of specific method names.

    so even a class that implements both __getitem__ and __len__ doesn't automatically become a Sequence, it needs to explicitly extend the ABC (at which point it would inherit an __iter__ implementation and become Iterable anyway).

2 of 3
0

It is an iterable. However you haven't inherited from abc.Iterable, so naturally Python won't report it as being descended from that class. The two things -being an iterable, and descending from that base class - are quite separate.

🌐
Real Python
realpython.com › ref › glossary › iterable
iterable | Python Glossary – Real Python
In Python, an iterable is an object that can return its elements one at a time, allowing you to loop over it using a for loop or any other iteration tool.
🌐
Reddit
reddit.com › r/javahelp › so what is iterable in java? confused with it and iterable.
r/javahelp on Reddit: So what is Iterable in Java? Confused with it and Iterable.
November 5, 2021 -

I just had to implement this to iterate through some private data structure. What threw me off is I couldn't index or do checks like I would with an array or list. I understand in general it is exactly like it sounds- used to iterate over some collection. Also that it is something we take for granted such as when using a foreach. That is all I get about it, it just seems like an inconvenience right now...

🌐
Reddit
reddit.com › r/learnprogramming › iterables in plain english.
r/learnprogramming on Reddit: Iterables in plain english.
May 19, 2024 - What’s the name for “you can give it whatever, as long as we can step through that whatever, one element at a time”? That’s an iterable. ... can I start at the beginning? can I advance one element at a time? will I know when I get to the end? ... some of them aren’t lists, but they all behave a little like lists. They might be all they keys in a hash table, or all the items in a set, or the cells in a array, that doesn’t matter. do they have the behaviors of being able to examine each one in turn? they are iterable. ... edit: also just to add, this is the kind of question that i would ask chatgpt.
🌐
The Python Coding Stack
thepythoncodingstack.com › the python coding stack › iterable: python's stepping stones
Iterable: Python's Stepping Stones - by Stephen Gruppetta
June 25, 2024 - As I described earlier, an iterable is an object you can loop through. On the other hand, an iterator is an object that helps you go through the elements of an iterable one by one, keeping track of where you are in the process.
🌐
DictAI
dictai.org › w › iterable
iterable - Definition
Computing & Programming: Describing an object or data type that possesses the ability to be iterated through or accessed element by element. Synonyms: loopable, enumerable, traversable, indexable, incrementable, multi-element ↗, sequential, repetitive, processable ↗ ... Sources: Wiktionary, ...
🌐
Python Morsels
pythonmorsels.com › iterable
What is an iterable? - Python Morsels
July 18, 2026 - An iterable is anything you're able to iterate over (iter-able). Iterables can be looped over and anything you can loop over is an iterable. Not every iterable is indexable or has a length.
Find elsewhere
🌐
JavaScript.info
javascript.info › tutorial › the javascript language › data types
Iterables
May 10, 2024 - So, the iterator object is separate from the object it iterates over. Technically, we may merge them and use range itself as the iterator to make the code simpler.
🌐
TheFreeDictionary.com
thefreedictionary.com › Iterable
Iterable - definition of Iterable by The Free Dictionary
Define Iterable. Iterable synonyms, Iterable pronunciation, Iterable translation, English dictionary definition of Iterable. a. 1. Capable of being iterated or repeated. Webster's Revised Unabridged Dictionary, published 1913 by G. & C. Merriam Co
🌐
Iterable
iterable.com › home
AI Customer Engagement Platform for Real-Time, Personalized Experiences
June 4, 2026 - Iterable is an AI customer engagement platform built for how customers behave today, helping brands respond in real time with unified data and optimization.
🌐
CDP
cdp.com › home › articles › what is iterable? features, pricing & alternatives
What Is Iterable? Features, Pricing & Alternatives | CDP.com
July 6, 2026 - Iterable’s data model reflects this shape. Profiles are JSON/NoSQL user records keyed on email or userId, combining user fields with event data and personalized through handlebars.js templates. It is a messaging-optimized store that starts once data has arrived and ends at delivery, with no mechanism for engagement outcomes to flow back into cross-channel identity resolution or predictive modeling.
🌐
Cogsci
python.cogsci.nl › basic › iterables
Iterables: list, dict, tuple, and set // Python Tutorials
In Python, an iterable object (or simply an iterable) is a collection of elements that you can loop (or iterate) through one element at a time. Simply put, an iterable is a list-like (or array-like) object.
🌐
W3Schools
w3schools.com › js › js_iterables.asp
JavaScript Iterables
A JavaScript iterable is an object that has a Symbol.iterator.
🌐
YouTube
youtube.com › watch
Learn Python iterables in 6 minutes! 🔂 - YouTube
#python #pythontutorial #pythonprogramming # Iterables = An object/collection that can return its elements one at a time,# allowing it to...
Published: July 1, 2024
🌐
ConnectWise
connectwise.com › blog › iterators-and-iterables-in-javascript
Iterators and Iterables in Javascript | ConnectWise
August 11, 2023 - As discussed above, an iterable is an object comprising an iterator—which is defined under the key Symbol.iterator. The iterator serves as the action definition for iteration, containing custom logic for the next() function.
🌐
YouTube
youtube.com › python morsels
What is an iterable in Python? - YouTube
An iterable is anything you're able to iterate over (iter-*able*). Iterables can be looped over and anything you can loop over is an iterable. Not every iter...
Published: December 5, 2022
Views: 539