[Types-sig] MetaClasses (Non-ASCII art)

M.-A. Lemburg mal@lemburg.com
Wed, 02 Dec 1998 10:40:04 +0100


Just van Rossum wrote:
> 
> I made a drawing of a possible meta object model (...or what I understand
> of it), but it went beyond ASCII, so you are kindly invited to visit:
>         http://starship.skyport.net/~just/meta/
> 
> Whether the dotted lines actually actually go through the objects or not is
> left vague on purpous. It depends on whether you'd like to write
>         instance.__class__
>         instance.__turtle__
> or
>         instance->in_class
>         instance->ob_type
> or
>         instance.__class__
>         instance.__class__.__nature__
> or (my fave, so this matches the drawing best)
>         instance.__class__
>         instance.__class__.__class__
> 
> Inheritance is deliberately left out of the picture, since it is defined
> (according to my model) by the metametaclass.
> 
> Does any of this make any sense to anyone?

It does... also looks a lot like what I posted to the egroups
list. I'll just repost it here for simplicity:

                    __class__            __bases__
                        .                    .
        ___________     .    ___________     .    ___________
       |           |    .   |           |    .   |           |
       |     v     |------->|     C     |------->|     B     |
       |___________|        |___________|        |___________|
             |                    |                    |
             |                    |                    |
             |                    |                    |
             v                    v                    v
        ___________          ________________________________
       |           |        |                                |
       | Instance  |        |            Class               |
       |___________|        |________________________________|
             |                              |
             |                              |
             |                              |
             v                              v
        _____________________________________________________
       |                                                     |
       |                    Object                           |
       |_____________________________________________________|
                         |      ^
                         |      |
                         |______| *)


       Down Arrows: __meta__


Arrows to the right indicate delegation which is implemented
by the meta objects (down arrows). Class objects will create
Instance objects when called. The latter are bound to the
Class objects by the __class__ attribute. Class objects
can be bound to each other by specifying a __bases__ tuple.

As opposed to Guido's picture, delegation is defined as abtract
form of behaviour. Instance objects resolve the issue by querying
their __class__ attribute, while Class objects search the
__bases__ tuple.

Note that Class and Instance may also be subclassed allowing
different behaviour to be implemented, e.g. if MyClass were
a subclass of Class and MyInstance a subclass of Instance,
MyClass could create MyInstance objects instead of Instance
objects.

Also note that the protocol used along the __meta__ arrows
has different semantics than along the right arrows: e.g.
__getattr__ is always called.

Here is a sample of the implied protocol:

Say you want to access the attribute 'v.a':

v.a
--> v.__meta__.__getattr__(v,'a')
--> check v.__dict__ for an 'a' entry
--> found: return v.__dict__['a']
--> else: # delegate the request to the Class object
---> v.__class__.__meta__.__getattr__(v.__class__,'a')
---> check v.__class__.__dict__ for 'a'
---> found: return v.__class__.__dict__['a'] (possibly wrapped as
method)
---> else: # delegate the request to the next base object
----> v.__class__.__bases__[0].__meta__.__getattr__(
        v.__class__.__bases__[0],'a')
----> etc.
--> if not found: # call the v.__class__.__getattr__ hook
--> return v.__class__.__getattr__(v,'a')

The above closely describes what the interpreter is doing
in the standard class implementation now.

Note that I left out the meta parts that are handled by the
Object object (a singleton): querying e.g. v.__meta__.__getattr__
would call v.__meta__.__meta__.__getattr__(v.__meta__,'__getattr__')
and so on (until Object is reached).

*) Not sure whether it's a good idea to introduce a loop
here, maybe __meta__ should just be None to indicate the root
of the meta-inheritance tree.

-- 
Marc-Andre Lemburg                               Y2000: 394 days left
---------------------------------------------------------------------
          : Python Pages >>> http://starship.skyport.net/~lemburg/  :
           ---------------------------------------------------------