Getting a list of all classes derived from a base class

V

Vijairaj R

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__)
 
D

Dylan Moreland

Vijairaj said:
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__)

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
 
A

Alex Martelli

Vijairaj R said:
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
 
V

Vijairaj

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
 
D

Dylan Moreland

Alex said:
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

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

Alex Martelli

Vijairaj said:
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
 
A

Alex Martelli

Dylan Moreland said:
...
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top