Needed: Real-world examples for Python's Cooperative Multiple Inheritance

Mark Wooding mdw at distorted.org.uk
Sat Nov 27 06:59:17 EST 2010


John Nagle <nagle at animats.com> writes:

> On 11/26/2010 4:21 PM, Mark Wooding wrote:
> > John Nagle<nagle at animats.com>  writes:
> >> @This catches the case where two classed both inherit from, say
> >> "threading.thread", each expecting to have a private thread.
> >
> > Why on earth would anyone do such a bizarre thing?  If you want a
> > private thread, then attach one as an attribute.  Inheriting is simply
> > madness.
>
> This must be from someone who hasn't used threads in Python.

Wrong again.

> The usual way to write a thread in Python is to subclass
> "threading.thread".  The subclass provides a "run" function, which
> will be called from the new thread.

Yes, it is.  Does that conflict with what I wrote?  No.

If you want you class to have a private thread, make /another/ class to
represent the behaviour of this private thread, and attach an instance
of this to the first class.  Or you can pass a closure or a bound method
to the thread constructor.  (That's probably cleaner, actually, but
doesn't fit culturally.)

> > If you stopped whining about how Python's object system might
> > theoretically go wrong if you try to use it like it was C++ and
> > started thinking about how to actually make effective use of the
> > features it offers -- features which long predate Python, and have
> > been thought about over many years, in languages such as Zetalisp,
> > Common Lisp, Dylan, Scheme, and variants of Smalltalk -- you might
> > got on much better.
>
>    Ah, fanboys.

Not exactly.  I collect programming languages like some people collect
postage stamps; it gives one a useful perspective.  I mentioned those
languages because they seem most historically relevant.  Zetalisp's
`Flavors' system introduced multiple inheritance; Common Lisp and Dylan
fix the linearization properly (eventually culminating in the C3
linearization algorithm); Scheme has no standardized object system, but
there are a number of -- mainly CLOS-like -- object systems available;
and Smalltalk is both the classic dynamic object-oriented language and a
single-dispatch contrast to the CLOS/Dylan generic-functions approach.

> Of those, I've written code in Common Lisp, Scheme, and Smalltalk.
> Most of the LISP variants really did objects very well; objects were
> an afterthought.  Smalltalk went a bit too far in the other direction;
> the "everything is an object" mindset was overdoing it.

CLOS actually does a remarkable integration job, bringing the existing
types into the object system; but, yes, the seams are still visible,
because you can't subclass some of the classes.

> Python is reasonably well balanced in the object area.  Everything
> isn't an object.  There are explicit classes, unlike the
> instance-copying model of Self and Javascript.

Is that a major win?  Self's prototype-based approach seems quite
capable of expressing anything you might want to express with classes,
and a few other things besides.  (The implementation works by attempting
to deduce class structures dynamically, so there's an isomorphism here,
of a sort, but the dynamism would make inventing classes on the fly
rather inconvenient.)  There's a significant difference between
Javascript and Self, by the way: a Self object can have multiple
`parent' slots, consequently with a form of multiple inheritance, while
Javascript is limited to single inheritance (unless you fake it up).

> However, multiple inheritance is something of a mess, as the original
> starter of this thread found when he tried to document how to use it.

Python's object system certainly isn't ideal.

The main problem that I see is that dynamic delegation with `super' is
hideously inconvenient to use, which means that programmers will tend
towards C++'s static delegation instead.

The Python object construction protocol (__new__ and __init__) is
somewhat simplistic; constructing instances of multiply inherited
classes in general requires a somewhat complicated dance with *args and
**kw arguments -- and you lose the ability to reject unknown arguments
-- which again leads to programmers taking shortcuts.

Most of the rest of the object system seems pretty sound to me.

> If you have real trouble writing documentation for a feature, it's
> usually because the feature is badly designed.

It might be that it was misunderstood.

There seem to be two obvious ways of learning a programming language.
One is to try and interpret its concepts in terms of concepts that you
already understand.  This works, but you end up having to `translate'
between the new language; if the translation is imperfect then you'll be
confused or frustrated.  There's a constant temptation to force one's
existing conceptual framework onto the new language -- to use it as if
it worked just like something else one is more familiar with that
doesn't quite work `right'.  The new language is `broken Blub with funny
syntax'.

The other is to try to understand it on its own terms.  This is the
harder road that leads to mastery.

-- [mdw]



More information about the Python-list mailing list