Review core Python semantics through decorators, dictionary hashing, generators, unpacking syntax, and memory management. Distinguish language guarantees from CPython behavior while connecting edge cases to API design, debugging, and safe resource cleanup.
# Python Language and Runtime Fundamentals
### Clarifying Questions to Ask
- Should answers describe CPython specifically or Python language semantics across implementations?
- Are short code examples welcome, and which Python version should be assumed?
### Part 1: Decorators
Explain what a Python decorator is, how `@decorator` syntax is evaluated, and how you would write a parameterized function decorator that preserves the wrapped function's metadata.
**Candidate hint:** Translate the `@` syntax into the equivalent assignment before discussing use cases.
#### What This Part Should Cover
- Decoration time and the callable transformation
- Closures for decorator arguments
- Metadata preservation and common state or binding pitfalls
### Part 2: Dictionaries, Hashability, and Collisions
Explain at a high level how a Python dictionary finds a key and resolves hash collisions. Then explain how to make a user-defined class safely hashable and why a list cannot be a dictionary key.
**Candidate hint:** Tie the answer to the contract between equality and hash stability, not merely to which built-in types are mutable.
#### What This Part Should Cover
- Hash lookup, equality checks, and collision handling
- The equality/hash contract and mutation risk
- Correct class choices, including when a class should remain unhashable
### Part 3: Generators
Explain generators, `yield`, lazy iteration, and the difference between a generator function and a normal function. Include how state and exceptions behave across iterations.
**Candidate hint:** Describe what is returned when the generator function is called, before its body runs to the first `yield`.
#### What This Part Should Cover
- Iterator protocol and suspended execution state
- Memory and streaming benefits
- Exhaustion, `StopIteration`, and cleanup considerations
### Part 4: Single and Double Star Syntax
Explain the meanings of `*` and `**` in function definitions, function calls, assignment unpacking, and collection literals. Identify at least one ordering or duplicate-key error.
**Candidate hint:** Separate collection packing/unpacking from keyword-only and positional-only call semantics.
#### What This Part Should Cover
- `*args`, `**kwargs`, and call-site unpacking
- Extended iterable unpacking and mapping expansion
- Signature boundaries and collision behavior
### Part 5: Garbage Collection
Explain Python memory management and garbage collection with appropriate implementation caveats. Include reference counting, cyclic garbage, finalization, and why object reclamation should not be treated as deterministic portable resource cleanup.
**Candidate hint:** Distinguish language guarantees from common CPython behavior.
#### What This Part Should Cover
- Reference ownership and cycle detection
- Finalizers, weak references, and implementation differences
- Context managers for external resources
### What a Strong Answer Covers
- Correct language semantics with CPython details clearly labeled
- Small examples that expose edge cases rather than hide them
- Invariants such as stable hashing and single-pass generator exhaustion
- Practical implications for API design, debugging, and resource safety
### Follow-up Questions
1. How does decorating an instance method interact with the descriptor protocol?
2. What can go wrong if an object's hash depends on a mutable field?
3. When would a generator expression be slower or less clear than a list comprehension?
4. Why can relying on `__del__` make cycle handling and shutdown behavior difficult?
Quick Answer: Review core Python semantics through decorators, dictionary hashing, generators, unpacking syntax, and memory management. Distinguish language guarantees from CPython behavior while connecting edge cases to API design, debugging, and safe resource cleanup.
Should answers describe CPython specifically or Python language semantics across implementations?
Are short code examples welcome, and which Python version should be assumed?
Part 1: Decorators
Explain what a Python decorator is, how @decorator syntax is evaluated, and how you would write a parameterized function decorator that preserves the wrapped function's metadata.
Candidate hint: Translate the @ syntax into the equivalent assignment before discussing use cases.
What This Part Should Cover Guidance
Decoration time and the callable transformation
Closures for decorator arguments
Metadata preservation and common state or binding pitfalls
Part 2: Dictionaries, Hashability, and Collisions
Explain at a high level how a Python dictionary finds a key and resolves hash collisions. Then explain how to make a user-defined class safely hashable and why a list cannot be a dictionary key.
Candidate hint: Tie the answer to the contract between equality and hash stability, not merely to which built-in types are mutable.
What This Part Should Cover Guidance
Hash lookup, equality checks, and collision handling
The equality/hash contract and mutation risk
Correct class choices, including when a class should remain unhashable
Part 3: Generators
Explain generators, yield, lazy iteration, and the difference between a generator function and a normal function. Include how state and exceptions behave across iterations.
Candidate hint: Describe what is returned when the generator function is called, before its body runs to the first yield.
What This Part Should Cover Guidance
Iterator protocol and suspended execution state
Memory and streaming benefits
Exhaustion,
StopIteration
, and cleanup considerations
Part 4: Single and Double Star Syntax
Explain the meanings of * and ** in function definitions, function calls, assignment unpacking, and collection literals. Identify at least one ordering or duplicate-key error.
Candidate hint: Separate collection packing/unpacking from keyword-only and positional-only call semantics.
What This Part Should Cover Guidance
*args
,
**kwargs
, and call-site unpacking
Extended iterable unpacking and mapping expansion
Signature boundaries and collision behavior
Part 5: Garbage Collection
Explain Python memory management and garbage collection with appropriate implementation caveats. Include reference counting, cyclic garbage, finalization, and why object reclamation should not be treated as deterministic portable resource cleanup.
Candidate hint: Distinguish language guarantees from common CPython behavior.
What This Part Should Cover Guidance
Reference ownership and cycle detection
Finalizers, weak references, and implementation differences
Context managers for external resources
What a Strong Answer Covers Guidance
Correct language semantics with CPython details clearly labeled
Small examples that expose edge cases rather than hide them
Invariants such as stable hashing and single-pass generator exhaustion
Practical implications for API design, debugging, and resource safety
Follow-up Questions Guidance
How does decorating an instance method interact with the descriptor protocol?
What can go wrong if an object's hash depends on a mutable field?
When would a generator expression be slower or less clear than a list comprehension?
Why can relying on
__del__
make cycle handling and shutdown behavior difficult?