Compare Python Generators, Decorators, and Context Managers

Quick Overview

Compare Python generators, decorators, and context managers through their protocols and execution timing, then combine them in a synchronous lazy file-reading example with deterministic cleanup on early exit or failure.

Compare Python Generators, Decorators, and Context Managers

Company: Hudson River Trading

Role: Site Reliability Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

## Question Compare Python generators, decorators, and context managers. For each construct, explain the protocol it relies on, when execution occurs, how state or resources are preserved, and one failure mode that a production implementation should handle. Include a runnable synchronous example showing how the three constructs cooperate when lazily reading records under timing instrumentation. Assign deterministic ownership of both the iterator and the file so an early `break` or an exception closes the file without relying on garbage collection. ### Constraints & Assumptions - Use ordinary synchronous Python; asynchronous variants may be discussed separately. - Distinguish an iterable from an iterator and a decorator factory from the wrapper it returns. - Do not claim that garbage collection is a substitute for deterministic resource release. ### Clarifying Questions to Ask - Should examples preserve function metadata and exceptions? - Is the context manager reusable or single-use? - Does the generator own the resource it reads, or is ownership external? ```hint Name the protocols Generators implement iteration, decorators transform callables, and context managers bracket a block through enter and exit hooks. ``` ### What a Strong Answer Covers - `yield`, suspension, lazy pull-based iteration, `StopIteration`, and cleanup on generator close. - Function wrapping, closures, `functools.wraps`, argument forwarding, and exception transparency. - `__enter__` and `__exit__`, suppression rules, and `contextlib.contextmanager`. - A wrapper generator whose `try/finally` times actual consumption, plus a caller-owned context or closing boundary that closes the wrapper and file on early exit. ### Follow-up Questions 1. What changes for async generators and async context managers? 2. Why can opening a file before returning a generator leak resources? 3. How would a decorator measure only consumed iteration time rather than generator creation time?

Quick Answer: Compare Python generators, decorators, and context managers through their protocols and execution timing, then combine them in a synchronous lazy file-reading example with deterministic cleanup on early exit or failure.

|Home/Software Engineering Fundamentals/Hudson River Trading
Hudson River Trading logo
Hudson River Trading
Aug 16, 2026, 12:00 AM
mediumSite Reliability EngineerTechnical ScreenSoftware Engineering Fundamentals
1
0

Question

Compare Python generators, decorators, and context managers. For each construct, explain the protocol it relies on, when execution occurs, how state or resources are preserved, and one failure mode that a production implementation should handle.

Include a runnable synchronous example showing how the three constructs cooperate when lazily reading records under timing instrumentation. Assign deterministic ownership of both the iterator and the file so an early break or an exception closes the file without relying on garbage collection.

Constraints & Assumptions

  • Use ordinary synchronous Python; asynchronous variants may be discussed separately.
  • Distinguish an iterable from an iterator and a decorator factory from the wrapper it returns.
  • Do not claim that garbage collection is a substitute for deterministic resource release.

Clarifying Questions to Ask Guidance

  • Should examples preserve function metadata and exceptions?
  • Is the context manager reusable or single-use?
  • Does the generator own the resource it reads, or is ownership external?

What a Strong Answer Covers Guidance

  • yield , suspension, lazy pull-based iteration, StopIteration , and cleanup on generator close.
  • Function wrapping, closures, functools.wraps , argument forwarding, and exception transparency.
  • __enter__ and __exit__ , suppression rules, and contextlib.contextmanager .
  • A wrapper generator whose try/finally times actual consumption, plus a caller-owned context or closing boundary that closes the wrapper and file on early exit.

Follow-up Questions Guidance

  1. What changes for async generators and async context managers?
  2. Why can opening a file before returning a generator leak resources?
  3. How would a decorator measure only consumed iteration time rather than generator creation time?
Loading comments...