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