views:

502

answers:

4

I've seen plenty of examples of people extracting all of the classes from a module, usually something like:

# foo.py
class Foo:
    pass

# test.py
import inspect
import foo

for name, obj in inspect.getmembers(foo):
    if inspect.isclass(obj):
        print obj

Awesome.

But I can't find out how to get all of the classes from the current module.

# foo.py
import inspect

class Foo:
    pass

def print_classes():
    for name, obj in inspect.getmembers(???): # what do I do here?
        if inspect.isclass(obj):
            print obj

# test.py
import foo

foo.print_classes()

This is probably something really obvious, but I haven't been able to find anything. Can anyone help me out?

+1  A: 

I don't know if there's a 'proper' way to do it, but your snippet is on the right track: just add import foo to foo.py, do inspect.getmembers(foo), and it should work fine.

int3
Whoa, I would have thought this would create a circular dependency or something, but it works!
frezned
+9  A: 

Try this:

import sys
current_module = sys.modules[__name__]

In your context:

import sys
def print_classes():
    for name, obj in inspect.getmembers(sys.modules[__name__]):
        if inspect.isclass(obj):
            print obj

And even better:

clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)

Because inspect.getmembers takes a predicate

Nadia Alramli
If I import classes in this module at the module level (i.e., `from optparse import OptionParser`) those modules are included in the print list. How might I avoid that?
phasetwenty
@phasetwenty, instead of inspect.isclass you can have something like: `inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)`
Nadia Alramli
+2  A: 

What about

g = globals().copy()
for name, obj in g.iteritems():

?

Krab
This is what I usually do. The other answers seems much more "clean" though, didnt know about them.
mizipzor
A: 

There was a [PEP] for a feature like this, but it was rejected.

Gary van der Merwe