Every operator, every built-in, every piece of syntax in Python is a question asked of your object. The data model is the list of questions.
__slots__ removes the per-instance dict. It saves real memory at scale, catches typos for free, and is the wrong default.
Duck typing fails at the call site, long after the mistake. ABCs and Protocols both fix that, in opposite directions.
Four ways to hold structured data in Python. The deciding question is not style — it is whether a typo should fail loudly.
Every operator and built-in in Python is asking your object a question. Answer it and your class behaves like a native type.
Inheritance gives a subclass everything, including what it should not have. The penguin problem, and what to do instead.
The question is only ever what the method needs — this instance, the class, or neither. Getting it wrong quietly breaks subclasses.
Python has no need for getters and setters, because @property lets you add validation later without changing a single caller.
A class without __repr__ wastes your time from the moment it exists. repr is for you, str is for the reader, and one of them has a sensible fallback.
self is a parameter name, not a keyword. __init__ does not create the object. And a class attribute is shared until the moment you assign through an instance.