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