An object is an instance (or not)?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Jan 29 02:16:16 EST 2015
Gregory Ewing wrote:
> 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.
I suspect that in Python it actually is, but I don't understand the
implementation of attribute look-ups well enough to be sure.
>> 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.
Actually, if you look at my example, you will see that it is a method and it
does get the self argument. Here is the critical code again:
from types import MethodType
polly.talk = MethodType(
lambda self: print("Polly wants a spam sandwich!"), polly)
The MethodType constructor takes a function and an instance, and returns a
method bound to that instance.
>> 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.
That's certainly not correct, because Python had classes and instances
before it had descriptors! Classes and instances go back to pre-1.5 days,
while descriptors were only introduced in 2.2. Besides, descriptors are
handled by the metaclass, so we could write a metaclass that doesn't handle
them.
>> 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.
Fair point about classmethods.
I think you're actually underestimating how close the symmetry between new-
style classes and instances actually is in Python.
> 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.
I don't understand this. I write dunder methods all the time. Ah wait, I
think I've got it. If you want (say) your class object itself to support
(say) the + operator, it isn't enough to write a __add__ method on the
class, you have to write it on the metaclass.
--
Steven
More information about the Python-list
mailing list