Skip to content

Instantly share code, notes, and snippets.

@ksheedlo
Created November 3, 2012 05:06
Show Gist options
  • Save ksheedlo/4006120 to your computer and use it in GitHub Desktop.
Save ksheedlo/4006120 to your computer and use it in GitHub Desktop.
Introspection for class discovery in Python
'''
Usage (from one directory up):
$ python -m introspection.introspect
'''
# The local package's name.
import introspection
import re
import os
import sys
# Taken shamelessly from unittest/loader.py.
VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
class Fooer(object):
def foo(self):
raise NotImplementedError('I don\'t know how to foo!')
class Fooer42(Fooer):
def foo(self):
return 'The answer is 42'
class FortyTwoFooer(Fooer):
def foo(self):
return 'Forty-two is the answer'
def get_name_from_path(path, top_level_dir):
path = os.path.splitext(os.path.normpath(path))[0]
_relpath = os.path.relpath(path, top_level_dir)
return _relpath.replace(os.path.sep, '.')
def get_named_module(name):
__import__(name)
return sys.modules[name]
def dispatch():
files = [
f for sublist in
[os.listdir(p) for p in introspection.__path__]
for f in sublist
]
module_names = [
get_name_from_path(os.path.abspath(m), os.path.abspath(os.path.curdir))
for m in files if VALID_MODULE_NAME.match(m)
]
modules = [
get_named_module('introspection.'+m) for m in module_names
]
for module in modules:
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and \
issubclass(obj, introspection.introspect.Fooer) and \
obj is not introspection.introspect.Fooer:
instance = Fooer.__new__(obj)
print instance.foo()
if __name__ == "__main__":
dispatch()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment