views:

195

answers:

3

While it is fairly trivial in Python to import a "child" module into another module and list its attributes, it becomes slightly more difficult when you want to import all child modules.

I'm building a library of tools for an existing 3D application. Each tool has its own menu item and sub menus. I'd like the tool to be responsible for creating its own menus as many of them change based on context and templates. I'd like my base module to be able to find all child modules and check for a create_menu() function and call it if it finds it.

What is the easiest way to discover all child modules?

+4  A: 

using dir() and imp module

dfa
imp looks like the exact module I need! Thanks.
Soviut
That's a pretty terse answer, I don't see why it was accepted. The documentation for dir() assumes your object already has attributes. Could you elaborate and say *how* one should use dir() for finding modules not yet imported?
bignose
+1  A: 

Hi! When I was a kind and just beginning programming in Python I've written this for my modular IRC bot:


    # Load plugins

    _plugins = []

    def ifName(name):
        try:
            return re.match('([^_.].+)\.[^.]+', a).group(1)
        except:
            return None

    def isValidPlugin(obj):
        from common.base import PluginBase
        try:
            if obj.__base__ == PluginBase:
                return True
            else:
                return False
        except:
            return False

    plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))]))
    for plugin_name in plugin_names:
        try:
            plugin = __import__('plugins.'+plugin_name, fromlist=['plugins'])
            valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)])
            _plugins.extend(valid_plugins)
        except Exception, e:
            logger.exception('Error loading plugin %s', plugin_name)

    # Run plugins

    _plugins = [klass() for klass in _plugins]

It's not secure or "right" way, but maybe it we'll be useful nevertheless. It's very old code so please don't beat me.

deno
Yes, you should use imp module like dfa mentioned.
deno
A: 

You can try globbing the directory:

import os
import glob

modules = glob.glob(os.path.join('/some/path/to/modules', '*.py'))

Then you can try importing them:

checked_modules
for module in modules:
    try:
        __import__(module, globals(), locals()) # returns module object
    except ImportError:
        pass
    else:
        checked_modules.append(module)
muhuk