MRO, __new__ and __slots__
Change class D(B, C) to class D(C, B) and predict how the hello chain changes.
How Python's object model really works, the way senior interviews probe it: method resolution order, descriptors, __new__ versus __init__, the GIL, garbage collection, decorators, generators versus iterators, __slots__ and context managers.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a context manager class called Collector with __enter__ returning a list and __exit__ that prints how many items were collected, even when an error happens inside the with.
Write a decorator count_calls that counts how many times a function was called and exposes the number as fn.calls, keeping the original name.
Create a class Meters(float) using __new__ so that Meters(3) is a float subclass instance that prints as 3.0 m when you call str() on it.
Explain it without notes
Explain MRO and what super() does in a diamond. Give the MRO of class D(B, C) where both extend A.
What is the difference between __new__ and __init__? When would you override __new__?
What is a descriptor? Name three built-in features that are implemented with descriptors.
What does the GIL do, and when do threads still help? What are your options for CPU-bound work?
How does CPython free memory? Why can a reference cycle survive del?
What is the difference between an instance method, a @classmethod and a @staticmethod? When is each the right choice?
What happens to hashing when a class defines __eq__? Why does that matter for sets and dict keys?
Expected output
MRO: ['D', 'B', 'C', 'A', 'object']
hello: ['D', 'B', 'C', 'A']
same object: True
AttributeError: 'Point' object has no attribute 'z' and no __dict__ for setting new attributes
has __dict__: False