Question presented to candidate:
"Some classes in our codebase declare __slots__ = ('x', 'y'). What does that actually change about the objects, why would you do it, and what breaks when you do?"
What a strong answer should cover:
__slots__declares a fixed set of attribute names; instances get fixed storage for them instead of a per-instance__dict__- Effects: less memory per object (no dict), and assigning an undeclared attribute raises
AttributeError - How: each slot is a member descriptor on the class (
type(Cls.__dict__['x'])ismember_descriptor) that reads and writes a fixed offset in the object - Inheritance rules: every class in the chain must define
__slots__(only new names) or a__dict__comes back; two bases with non-empty slots cannot be combined - Costs: no weak references unless
'__weakref__'is listed, no class-attribute defaults with the same name, novars()orcached_property;@dataclass(slots=True)(3.10+) generates them for you
Clarifying questions expected:
- How many instances are alive at once? (the saving only matters with many objects)
- Is the class part of a hierarchy, or used with weak references or
cached_property?
Code / implementation expected: Optional β a slotted class next to a plain one showing the missing __dict__ and the AttributeError on a typo.