› Forums › CS50’s Introduction to Computer Science by Harvard University on Edx › Week 6: Python › HarvardX CS50P: CS50’s Introduction to Programming with Python › Week 2: Python › What Happens If a Class Has __iter__() But Not __next__() — And Vice Versa?
- This topic is empty.
-
AuthorPosts
-
May 18, 2026 at 5:21 am #6612
This is one of the most important conceptual questions in understanding Python iteration.
To understand it properly, we must clearly separate:
- iterable
- iterator
First Important Clarification
A Python list is mainly an:
Iterable
not an iterator itself.
Example:
numbers = [1, 2, 3]This object has:
__iter__()but the actual iteration is usually handled by a separate iterator object internally.
What Happens Internally for a List?
When you do:
numbers = [1, 2, 3] iterator = iter(numbers)Python internally creates something conceptually like:
<list_iterator object>That iterator object contains:
__next__()So:
Object Main Role list Iterable list_iterator Iterator
Case 1 — Class Has
__iter__()But No__next__()Example:
class MyClass: def __iter__(self): return selfNow:
obj = MyClass() iter(obj)works.
BUT:
next(obj)fails.
Why?
Because Python expects the returned iterator object to implement:
__next__()Without it, Python does not know:
“How to fetch the next value.”
Error Example
class MyClass: def __iter__(self): return self obj = MyClass() next(obj)Output:
TypeError: 'MyClass' object is not an iterator
What Does This Mean Conceptually?
If a class has only:
__iter__()it means:
“This object knows how iteration should begin, but does not know how to produce values.”
So the iteration mechanism is incomplete.
Real Meaning of
__iter__()AloneHaving only:
__iter__()usually means:
“This object can create or return an iterator.”
That returned iterator might be:
- another object
- a generator
- a built-in iterator
Example of Proper Iterable with Only
__iter__()class MyNumbers: def __iter__(self): return iter([1, 2, 3])Usage:
obj = MyNumbers() for x in obj: print(x)Output:
1 2 3Here:
MyNumbersis iterable- the returned list iterator handles
__next__()
Very important distinction.
Case 2 — Class Has
__next__()But No__iter__()Example:
class MyClass: def __next__(self): return 1Now:
next(obj)works.
BUT:
iter(obj)fails.
Error Example
obj = MyClass() iter(obj)Output:
TypeError: 'MyClass' object is not iterable
What Does This Mean Conceptually?
If a class has only:
__next__()it means:
“This object knows how to produce next values, but Python does not know how iteration should start.”
So Python cannot use it in a normal loop.
Proper Iterator Structure
A true iterator usually implements BOTH:
__iter__() __next__()Example:
class Counter: def __init__(self): self.n = 1 def __iter__(self): return self def __next__(self): if self.n <= 3: value = self.n self.n += 1 return value raise StopIterationNow this works fully:
c = Counter() for x in c: print(x)Output:
1 2 3
Very Important Insight
If Object Has Meaning __iter__()onlyCan provide an iterator __next__()onlyCan produce values but not iterable properly Both Fully functional iterator
The Most Common Design in Python
Usually:
- collections are iterables
- separate iterator objects handle traversal
Example:
Iterable Iterator Produced list list_iterator tuple tuple_iterator dict dict_keyiterator file file iterator
Key Takeaway
__iter__()Means:
“I can provide an iterator.”
__next__()Means:
“I can provide the next value.”
Both Together
Means:
“I am a complete iterator object.”
-
AuthorPosts
- You must be logged in to reply to this topic.
