Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting a list of all classes derived from a base class

1 view
Skip to first unread message

Vijairaj R

unread,
Apr 3, 2006, 12:51:45 AM4/3/06
to
Hi,
I have a requirement to findout all the classes that are derived from a
single base class.

This is how I do it currently.

class Test:
case = []

class Test1(Test):
Test.case.append("Test1")

class Test2(Test):
Test.case.append("Test2")

1. Is there a better way of doing this.
2. Is there a way to generalize the Test.case.append("TestN")
statements to something like
Test.case.append(__myclass__)

--
Warm Regards,
Vijairaj

Dylan Moreland

unread,
Apr 3, 2006, 1:07:36 AM4/3/06
to

If you're willing to use metaclass madness:

class TestMeta(type):
def __init__(cls, name, bases, dct):
if bases == (object,): return # Prevent the appending of Test
cls.case.append(cls)

class Test(object):
__metaclass__ = TestMeta
case = []

class Test1(Test): pass
class Test2(Test): pass

print Test.case

Alex Martelli

unread,
Apr 3, 2006, 2:48:04 AM4/3/06
to
Vijairaj R <Vijai...@gmail.com> wrote:
...
> class Test:

do not use old-style classes: they exist ONLY for backwards
compatibility.

Make you class Test new-style:

class Test(object):
...


and you can call Test.__subclasses__() to get a list of all extant
subclassed of Test at any time.


Alex

Vijairaj

unread,
Apr 3, 2006, 3:19:11 AM4/3/06
to
Thanks Dylan and Alex, that was a new learning for me.

but both the solutions don't work in jython 2.1 is there an alternative
that will work with jython2.1

--
Thanks,
Vijairaj

Dylan Moreland

unread,
Apr 3, 2006, 3:50:48 AM4/3/06
to

Thanks Alex. That's a new one to me -- new-style classes have so many
strange properties.

Alex Martelli

unread,
Apr 3, 2006, 11:32:06 AM4/3/06
to
Vijairaj <Vijai...@gmail.com> wrote:

> Thanks Dylan and Alex, that was a new learning for me.
>
> but both the solutions don't work in jython 2.1 is there an alternative
> that will work with jython2.1

Alas, no: your simple idea is essentially the best you can do in any
implementation of Pyhon at 2.1 level.

To put a positive spin on it: if there *WEREN'T* some things that are
much easier and slicker in Python 2.4, with all the years and the work
we've put into Python since 2.1's times, now THAT would be bad!-)

I do hope that Jython does eventually "grow up" to a more modern version
of Python -- unfortunately, I'm too rusty with Java, and not involved
enough in JVM work day by day, to actually help out there, and
apparently so are most potential contributors to Jython:-(


Alex

Alex Martelli

unread,
Apr 3, 2006, 11:32:07 AM4/3/06
to
Dylan Moreland <dylan.m...@gmail.com> 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

0 new messages