19

I've got a module written in Python. I now want to import it into another script and list all classes I defined in this module. So I try:

>>> import my_module
>>> dir(my_module)
['BooleanField', 'CharField', 'DateTimeField', 'DecimalField', 'MyClass', 'MySecondClass', 'ForeignKeyField', 'HStoreField', 'IntegerField', 'JSONField', 'TextField', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'datetime', 'db', 'division', 'os', 'struct', 'uuid']

The only two classes which I defined in my_module are MyClass and MySecondClass, the other stuff are all things that I imported into my_module.

I now want to somehow be able to get a list of all classes which are defined in my_module without getting all the other stuff. Is there a way to do this in Python?

kramer65
  • 50,427
  • 120
  • 308
  • 488
  • 2
    While it is possible to get this information, trying to do so is fragile and results in unobvious behaviour. In general, reflection is very useful for debugging, but should be considered very carefully before being used in actual production code. – Sven Marnach Mar 22 '14 at 14:13
  • To document which names may be used outside (public), you could define `__all__` attribute: `[cls for name in your_module.__all__ for cls in [getattr(your_module, name)] if inspect.isclass(cls)]` it works even if the class is defined in a submodule but you want it to be available from toplevel module. Try it with `asyncio` module, to see what I mean – jfs Mar 24 '14 at 06:58

3 Answers3

50

Use the inspect module to inspect live objects:

>>> import inspect
>>> import my_module
>>> [m[0] for m in inspect.getmembers(my_module, inspect.isclass) if m[1].__module__ == 'my_module']

That should then work, getting every class defined within that my_module.

anon582847382
  • 19,907
  • 5
  • 54
  • 57
8

You can use Python Class Browser

import pyclbr
module_name = 'your_module'
module_info = pyclbr.readmodule(module_name)
print(module_info)

for item in module_info.values():
    print(item.name)

it will list all classes defined in your_module

Most Wanted
  • 6,254
  • 5
  • 53
  • 70
1

If you really want to use dir(), here it is:

>>> import module
>>> [eval("module." + objname) for objname in dir(module) if type(eval("module." + objname)) is type]

or (script form)

import module
classes = []
for objname in dir(module):
    obj = eval("module." + objname)
    if type(obj) is type:
        classes.append(obj)
print(classes)

But this uses the "eval" function, and is really not safe for use. I'd stick to the chosen answer

Community
  • 1
  • 1
Epic Wink
  • 796
  • 13
  • 18