Advanced Python
Generators, decorators, context managers, async I/O and flexible interfaces.
Generators
def chunks(values: list[int], size: int):
for index in range(0, len(values), size):
yield values[index:index + size]Generators produce values lazily and are useful for streams or data too large to hold in memory.
Decorators
Decorators wrap functions with reusable behavior such as timing, caching or authorization. Preserve metadata with functools.wraps and keep hidden behavior limited.
Context managers
Use with for resources that require cleanup. Implement a context manager with contextlib.contextmanager or __enter__ and __exit__.
Async I/O
import asyncio
async def main() -> None:
results = await asyncio.gather(fetch("/a"), fetch("/b"))
print(results)
asyncio.run(main())Async helps when tasks spend time waiting for network or disk. It does not make CPU-heavy Python code faster. Use semaphores to limit concurrency, set timeouts and support cancellation.
Interfaces and dependency injection
Use Protocol to describe required behavior and inject dependencies through constructors or functions. This keeps business logic independent from databases, HTTP clients and frameworks.