Steven D'Aprano wrote:
In fairness, "inherit" is standard terminology for the way instances get their behaviour from their class.
I'm not sure that's true, but even if it is, it's not the same kind of inheritance relationship as exists between a class and a base class, which was my point.
Also, you can override methods *on the instance*:
I wouldn't call that a method -- it's just an instance attribute that happens to be a function. You can tell it's not a method because it doesn't get a 'self' argument.
In Python, obj.talk performs the following (grossly simplified) process: * search the instance for an attribute "talk" * search the class * search all the base classes * fail (simplified because I have ignored the roles of __getattr__ and __getattribute__, of metaclasses, and the descriptor protocol)
By ignoring the descriptor protocol, you're simplifying away something very important. It's the main thing that makes the instance-of relation different from the subclass-of relation.
The normal way of giving a class methods that are callable from the class is to define them on the class with the classmethod or staticmethod decorators. Using a metaclass is usually overkill :-)
True, but I was trying to illustrate the symmetry between classes and instances, how the classic OOP ideas of Smalltalk et al are manifest in Python, and to show that classes *can* "participate fully in OOP" just like any other objects if you want them to. Python's "class methods" are strange beasts that don't have an equivalent in the classic OOP model, so they would only have confused matters. And there are cases where you *do* need a metaclass, such as giving a __dunder__ method to a class, so it's useful to know how to do it just in case.
An early essay on Python metaclasses was subtitled "The Killer-Joke".
Quick, translate this post into German before anyone sees too much of it! -- Greg -- https://mail.python.org/mailman/listinfo/python-list