[Python-3000] Implementations: A syntax for extending method dispatching beyond type/class inheritance

Jim Jewett jimjjewett at gmail.com
Mon Dec 11 22:59:16 CET 2006


On 12/4/06, Bill Janssen <janssen at parc.com> wrote:
> Jim Jewett writes:
> > On 12/3/06, Bill Janssen <janssen at parc.com> wrote:
> > > > Implementations are used to make Method Dispatching more flexible by
> > > > allowing a class to claim that it acts like another class/type even
> > > > though it is not derived from that class/type.

> > > I'm not sure just what this adds over the simple "change_class"
> > > function that I've posted twice already.  Is there an implementation
> > > efficiency argument here?

> > (1)  Interfaces can be placed on a separate (presumably light-weight)
> > inheritance hierarchy.
>
> I know it looks this way, but I think you'd just be changing one
> inheritance mechanism for another.  No one would use the one that's
> already there; they'd just use this one instead.  And I don't really
> see how it's lighter-weight -- can you explain that?

As an example (details could change later)

When looking up an attribute (such as a method), look up the regular
Base class inheritance chain.  Changes to this chain are (as today)
bad form, so the MRO results can be cached on the fully-derived type.
There is an (unenforced) assumption that base classes are concrete,
which will help some people to get their heads around your code.

If the attribute is not found, instead of throwing an error, look in
the interface chain as well.  There is a fair chance that this list of
interfaces will change even after class creation.  There is a fair
chance that attributes will be methods which just raise an error
(because they should have been overridden).

Note that this does mean (the logical equivalent of) tracing the MRO tree twice:

    Interface I: src="interface"

    class A:
        implements I
        y="normal"
    a=A()

    class B
        src="class"
        y="hidden"
    b=B()

    class C(A, B):
        pass
    c=C()

    c.y is a.y       # because A is earlier on the inheritance tree, but ...
    c.src is b.src # because interfaces are always after "concrete" members

> > (2)  There is are efficiency (and security) concerns with changing
> > bases in an arbitrary manner.  Changing them only at the back (where
> > they cannot hide existing attributes) may be safer and easier.  (I'm
> > not certain of this; but I'm not ready to rule it out either.)

> I'm not sure how this is supposed to work, though, without changing
> bases.  I started to write up a sentence much like you wrote above,
> then didn't, because I couldn't see how you could do this without
> changing bases.

Bases can be changed even today.  But if changes are restricted to
"interface" bases, then the same "it doesn't change often"
optimizations used today can still be made for "regular" attributes.

-jJ


More information about the Python-3000 mailing list