Advanced Generator Patterns
Coroutine Generators
Coroutines extend generator functionality by allowing two-way 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
def sub_generator():
yield 1
yield 2
yield 3
def delegating_generator():
yield 'start'
yield from sub_generator()
yield 'end'
for item in delegating_generator():
print(item)
Asynchronous Generator Patterns
async def async_generator():
for i in range(3):
await asyncio.sleep(1)
yield i
async def main():
async for value in async_generator():
print(value)
Generator Composition Workflow
graph TD
A[Primary Generator] --> B[Delegate Generator]
B --> C[Sub-Generator 1]
B --> D[Sub-Generator 2]
B --> E[Sub-Generator N]
Advanced Generator Techniques
Technique |
Description |
Use Case |
Chaining |
Combine multiple generators |
Data processing pipelines |
Filtering |
Apply conditions during iteration |
Selective data extraction |
Transformation |
Modify generator output |
Data preprocessing |
Complex Generator Composition
def infinite_sequence():
num = 0
while True:
yield num
num += 1
def squared_sequence():
for num in infinite_sequence():
yield num ** 2
if num > 10:
break
def filtered_sequence():
for square in squared_sequence():
if square % 2 == 0:
yield square
## Composing generators
for value in filtered_sequence():
print(value)
Generator as State Machines
def simple_state_machine():
state = 'IDLE'
while True:
command = yield state
if command == 'ACTIVATE':
state = 'RUNNING'
elif command == 'DEACTIVATE':
state = 'IDLE'
## State machine usage
machine = simple_state_machine()
print(next(machine)) ## IDLE
print(machine.send('ACTIVATE')) ## RUNNING
- Generators provide memory-efficient iteration
- Minimal overhead for complex data transformations
- Suitable for large-scale data processing
Error Handling in Advanced Generators
def robust_generator():
try:
yield from complex_operation()
except Exception as e:
yield f"Error: {e}"
By mastering these advanced generator patterns, developers can create sophisticated, memory-efficient, and flexible data processing tools in Python, leveraging the full potential of generator functionality.