The data model
SeniorDunder methods, attribute lookup, and how Python's object protocols fit together.
2 questions · answers hidden
01How does attribute lookup work for `obj.x`?
#q-how-does-attribute-lookup-work-for-objxRoughly, for an instance:
- Python looks up
type(obj).__mro__for a data descriptor namedx(defines__set__/__delete__, e.g.property). If found, its__get__wins. - Otherwise it checks
obj.__dict__forx. - Otherwise it checks the class MRO again for a non-data descriptor (e.g. a plain function, which becomes a bound method) or a plain class attribute.
- Otherwise it calls
type(obj).__getattr__(obj, "x")if defined, else raisesAttributeError.
__getattribute__is what actually runs this whole algorithm;__getattr__is only the fallback for the miss case.- Python looks up
02What's the difference between `__str__`, `__repr__`, and when is each used?
#q-whats-the-difference-between-__str__-__repr__-and-when-is-ea__repr__is for developers: unambiguous, ideallyeval-able, shown in the REPL, in containers ([obj]), and by the debugger. Always define it.__str__is for end users / readable output; used bystr()andprint(). Falls back to__repr__if not defined.
A good default
__repr__isf"{type(self).__name__}(name={self.name!r})".