Class, Iterator, and Generator in Python
Class, Iterator, and Generator in Python
1. Class
- Definition: A class is a blueprint for creating objects. It defines attributes (data) and methods (functions) that operate on the data.
- Purpose: To encapsulate data and functionality together.
- Example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
person = Person("Alice", 30)
print(person.greet())
2. Iterator
- Definition: An object that implements the
__iter__() and __next__() methods to allow sequential access to its elements.
- Purpose: To iterate over a collection (like lists, tuples, etc.) without exposing its underlying structure.
- Example:
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current > self.end:
raise StopIteration
else:
self.current += 1
return self.current - 1
counter = Counter(1, 5)
for num in counter:
print(num)
3. Generator
- Definition: A special type of iterator defined using a function with the
yield keyword. Generators are used to produce items one at a time as they are needed.
- Purpose: To save memory by yielding values lazily instead of generating all values at once.
- Example:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num)
print("\nClass\n")
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
person = Person("Alice", 30)
print(person.greet())
print("\nIterator\n")
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current > self.end:
raise StopIteration
else:
self.current += 1
return self.current - 1
counter = Counter(1, 5)
for num in counter:
print(num)
print("\nGenerator\n")
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num)
Interview angle
- “Iterator protocol?” -
__iter__ returns an iterator, __next__ returns the next item or raises StopIteration. An iterable only needs __iter__; an iterator needs both and returns itself from __iter__.
- “Why write a generator instead of an iterator class?” - far less code and the state is implicit in the function’s suspension point. Write the class only when you need extra methods or attributes on the iterator itself.
- “What does laziness buy you?” - constant memory over arbitrarily large sequences, and the ability to model infinite streams. It’s why you read a large file line by line rather than calling
.readlines().