5 exercises — decorators, generators, context managers, asyncio/async-await, and type hints. The Python-specific terms you need to discuss code fluently in English.
0 / 5 completed
Python-specific English vocabulary reference
decorator — @-syntax wrapper function; e.g. @property, @staticmethod, @app.route()
generator — function with yield; produces values lazily one at a time
context manager — with statement; guarantees cleanup via __enter__/__exit__
coroutine — async def function; can be paused with await
type hint — annotation like def f(x: int) -> str:; checked by mypy, not enforced at runtime
1 / 5
A code review comment says: "This function would be cleaner as a decorator." In Python, a decorator is:
A decorator in Python is a higher-order function — it wraps another function to add behaviour. Syntax: @decorator_name above the function definition.
Common built-in decorators: • @staticmethod — method that doesn't receive self or cls • @classmethod — method that receives the class (cls) instead of an instance • @property — turns a method into a read-only attribute • @functools.cache / @lru_cache — memoisation
Custom use cases: @app.route() in Flask, @login_required in Django, @retry for automatic retries, @dataclass for auto-generating class methods.
2 / 5
A mentor says: "Use a generator here instead of building the whole list in memory." What is a Python generator and why does it save memory?
A generator uses yield to produce values one at a time. The function's state is suspended between yields and resumed on the next call to next().
Memory benefit: instead of list(range(10_000_000)) — 80+ MB in memory — a generator expression (x for x in range(10_000_000)) uses only a few bytes, because it calculates each value on demand.
Key vocabulary: • yield — produces a value and suspends the function • yield from — delegates to another iterable/generator • lazy evaluation — compute values only when needed • generator expression — (expr for x in iterable) — like a list comprehension but lazy • next(gen) — gets the next value; raises StopIteration when exhausted
3 / 5
A senior engineer reviews your file-reading code and says: "You should use a context manager here." They replace f = open('data.csv') with with open('data.csv') as f:. What does the with statement guarantee?
A context manager implements the context management protocol (__enter__ and __exit__ methods). The with statement calls __exit__ automatically when the block ends — whether normally or due to an exception.
Without with: if an exception occurs before f.close(), the file handle leaks. With enough leaked handles, the OS runs out of file descriptors.
Common context managers: • open() — closes files automatically • threading.Lock() — releases lock even if code raises • tempfile.TemporaryDirectory() — deletes temp dir when done • Database connections/sessions — commits or rolls back • unittest.mock.patch() — restores mocked objects after test
Custom context managers: implement __enter__/__exit__, or use @contextlib.contextmanager with yield.
4 / 5
A job description requires "Python async/await proficiency." A teammate asks: "What does asyncio actually solve?" What is the correct explanation?
asyncio implements cooperative multitasking — a single-threaded event loop that switches between tasks when they are waiting for I/O.
Key vocabulary: • coroutine — a function defined with async def that can be paused with await • event loop — the scheduler that runs coroutines and handles I/O events • await — suspends the current coroutine and hands control back to the event loop • I/O-bound — workloads that spend time waiting for external resources (network, disk, database) — asyncio shines here • CPU-bound — workloads that compute heavily — asyncio doesn't help; use multiprocessing or concurrent.futures.ProcessPoolExecutor
Frameworks built on asyncio: FastAPI, aiohttp, SQLAlchemy (async), asyncpg.
asyncio vs threading: both enable concurrency, but asyncio avoids thread-safety issues (no shared mutable state by default), uses less memory, and scales better for high I/O concurrency.
5 / 5
A tech lead says: "Use type hints and run mypy on this module before merging." What are type hints in Python and why does the team use them?
Type hints (PEP 484+) are optional annotations added to variable, parameter, and return value declarations in Python.
Runtime behaviour: Python ignores type hints by default. They live in __annotations__ but are not enforced. mypy and pyright analyse them statically.
Why teams use type hints: • Catch bugs before runtime (wrong argument type passed to a function) • IDE autocompletion and refactoring support • Documentation that can't go out of date (it's in the code) • Required by some frameworks (FastAPI uses Pydantic models heavily based on type hints)