Last pop quiz: what makes Python an object-oriented language?
Ah, hm. It can’t be classes, or I’d tell you you’re wrong. So what is it? [...]
self? No, that’s not a keyword or anything; it’s just the de facto standard name
for the first argument. So what makes self work?
That’s close enough, really. The answer is descriptors, which are basically “the
things that make self work”.
From another blog post on the same site [1]:
A descriptor is just an object; there’s nothing inherently special about it.
Like many powerful Python features, they’re surprisingly simple. To get the
descriptor behavior, only three conditions need to be met:
1. You have a new-style class. [...]
It therefore follows logically that Python code using old-style classes is not object-oriented, and that Python was not an object-oriented language prior to the introduction of descriptors.
[1]: https://eev.ee/blog/2012/05/23/python-faq-descriptors/