An object is an instance (or not)?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jan 28 06:52:46 EST 2015


Gregory Ewing wrote:

> Mario Figueiredo wrote:
>> I couldn't think of a way to
>> demonstrate that a class object does not participate in its own
>> inheritance rules. Only instances of it can.
> 
> I think I may see where your reasoning is going astray.
> You think that an instance "inherits" methods from its
> class in the same way that a subclass inherits methods
> from its base class.

In fairness, "inherit" is standard terminology for the way instances get
their behaviour from their class.

Also, you can override methods *on the instance*:


py> class Parrot(object):
...     def talk(self):
...             print("Polly wants a cracker!")
...
py> polly = Parrot()
py> polly.talk()
Polly wants a cracker!
py> from types import MethodType
py> polly.talk = MethodType(
...     lambda self: print("Polly wants a spam sandwich!"), polly)
py> polly.talk()
Polly wants a spam sandwich!



> But thinking of the instance-class relationship as
> an inheritance relationship is misleading. It's more
> accurate to say that a class *defines* the methods
> that its instances have. The class inherits methods
> from its base class, but those methods still apply to
> instances of the class, not the class itself.

I won't speak for other OOP models, but I don't think that is true in
Python. 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)


That's more or less the same as what happens whether obj is a class object
or a non-class object. I don't know what attribute lookup *literally* uses
the exact same code for looking up attributes on an instance or a class,
but it wouldn't surprise me if it does.


> That doesn't mean the class itself can't be given
> methods, though. The methods of the class are defined
> by its metaclass, and the metaclass inherits methods
> from *its* base class, etc.


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 :-)



> Here's a diagram:
> 
> +------+                  +------------+
> | type |                  | base class |
> +------+                  +------------+
>     ^                           ^
>     | subclass of               | subclass of
>     |                           |
> +-----------+              +-------+              +----------+
> | metaclass |<-------------| class |<-------------| instance |
> +-----------+  instance of +-------+  instance of +----------+
> 
> It should be clear from this that the relationship
> between an instance and its class is exactly the same
> as that between a class and its metaclass, including
> inheritance relationships.
> 
> The diagram can be extended indefinitely far to the
> left -- the metaclass could be an instance of a
> meta-metaclass, etc. (Although there's an old standing
> joke in the Python world that metaclasses make your
> head explode, so I hate to think what a meta-metaclass
> would do -- probably take out a whole floor of the
> office building you work in. Meta-meta-metaclasses are
> right out.)

An early essay on Python metaclasses was subtitled "The Killer-Joke". 




-- 
Steven




More information about the Python-list mailing list