Advanced Generator Patterns
Coroutine Generators
Coroutines extend generator functionality by allowing bidirectional communication and complex state management.
def coroutine_example():
while True:
x = yield
print(f"Received: {x}")
## Coroutine usage
coro = coroutine_example()
next(coro) ## Prime the coroutine
coro.send(10)
coro.send(20)
Generator Delegation
Yield From Mechanism
def sub_generator():
yield 1
yield 2
def delegating_generator():
yield from sub_generator()
yield 3
for value in delegating_generator():
print(value)
Asynchronous Generator Patterns
graph TD
A[Generator] --> B[Async Processing]
B --> C[Yield Results]
C --> D[Non-Blocking Execution]
Advanced Generator Techniques
Technique |
Description |
Use Case |
Chaining |
Connecting multiple generators |
Data processing |
Filtering |
Selective value generation |
Data transformation |
Infinite Generators |
Continuous value production |
Stream processing |
Complex Generator Composition
def infinite_counter(start=0):
while True:
yield start
start += 1
def filter_even(generator):
for value in generator:
if value % 2 == 0:
yield value
## Composing generators
even_numbers = filter_even(infinite_counter())
for _ in range(5):
print(next(even_numbers))
Generator Pipeline Pattern
def data_pipeline(data):
## Transformation stage 1
transformed = (x * 2 for x in data)
## Filtering stage
filtered = (x for x in transformed if x > 10)
## Final processing
result = sum(filtered)
return result
data = [1, 5, 10, 15, 20]
print(data_pipeline(data))
Context Management in Generators
from contextlib import contextmanager
@contextmanager
def generator_context():
print("Setup")
try:
yield
finally:
print("Cleanup")
with generator_context():
print("Inside context")
- Lazy Evaluation
- Memory Efficiency
- Minimal State Maintenance
Error Handling in Generators
def error_handling_generator():
try:
yield 1
yield 2
raise ValueError("Intentional error")
except ValueError:
yield "Error handled"
gen = error_handling_generator()
print(next(gen))
print(next(gen))
print(next(gen))
LabEx Advanced Techniques
At LabEx, we recommend mastering these advanced generator patterns to create more robust and efficient Python applications.
Real-world Application: Data Streaming
def data_stream_generator(source):
for item in source:
## Complex processing
processed_item = process_data(item)
yield processed_item
def process_data(item):
## Simulate complex transformation
return item * 2
Generator Design Principles
- Minimize memory footprint
- Maintain clear state transitions
- Implement robust error handling
- Support flexible composition
By understanding and implementing these advanced generator patterns, developers can create more elegant, efficient, and powerful Python applications.