Dylan Moreland <[EMAIL PROTECTED]> wrote: ... > > do not use old-style classes: they exist ONLY for backwards > > compatibility. ... > > and you can call Test.__subclasses__() to get a list of all extant > > subclassed of Test at any time. ... > Thanks Alex. That's a new one to me -- new-style classes have so many > strange properties.
You're welcome! Actually, IMHO, it's the _legacy_ style classes which have odd quirks, as they fail to distinguish cleanly between a type/clas and its instances, and provide a unified conceptual model. For example, given an object X which has an attribute named __call__ (has it directly, not from its class/type), does calling X() call X.__call__()? In the new-style model, the answer is clear and sharp: no. Special methods that Python internally invokes always come from the type/class, never from the object itself. In the legacy model, the answer is fuzzy and muddled: "mostly yes _except_ if X is a class then no", because if X is a class then X.__call__ is meant to influence the behavior of calling *instances* of X, only, not that of calling X itself. This kind of "conceptual muddle" in oldstyle classes could not be solved without breaking backwards compatibility, so a parallel concept of "newstyle" was introduced, and behaves much more simply and predictably; in Python 3.0, oldstyle will go away -- good riddance!-) This is quite separate from the fact that, since Python 2.2 where newstyle objects were introduced, some handy features such as __mro__ and __subclasses__ were introduced -- not to legacy classes, of course, since you should not use those in new code (not for conceptual reasons). The "conceptual" side of things can be boiled down to descriptors (and to a lesser extent, custom metaclasses, but those are rare beasts). Alex -- http://mail.python.org/mailman/listinfo/python-list