Hi guys,
Im a making a program where i need to be able to specify a folder and have my program import every module from that folder into my program... I was wondering how i would go about it. I can't use something like eval.

But yeah, help would be greatly appreciated :)

Cheers
Paul

You could go this way, assuming that you have a folder named 'mypackage' wich contains a file '__init__.py'

# tested with py 2.6
import os
import mypackage

def module_names(package):
    # This only finds python modules which name doesn't start with '__'
    folder = os.path.split(package.__file__)[0]
    for name in os.listdir(folder):
        if name.endswith(".py") and not name.startswith("__"):
            yield name[:-3]


def import_submodules(package):
    names = list(module_names(package))
    m = __import__(package.__name__, globals(), locals(), names, -1)
    return dict((name, getattr(m, name)) for name in names)

if __name__ == "__main__":
    mydict = import_submodules(mypackage)
    from pprint import pprint
    pprint(mydict)

Hmm... I have always wondered.. What is the significance of the __init__.py filename? I know what __init__ but what does it do in relation to files?

When the package system was added to python, the idea was that a folder could be a python module and it could have submodules. If the folder is a module, you need some place to put python code which runs when the module is imported. This is the role of the __init__.py file, which is often empty. The python developpers defined the rule that a folder without __init__.py is not recognized by python as a python module, but I read somewhere that this rule may change in a version of python 3.

Edited 7 Years Ago by Gribouillis: n/a

So.. By importing the program into its own __init__ module it then imports everything in the folder... Or am i still missing the point?

It's true, suppose that mypackage contains __init__.py, foo.py, bar.py and baz.py. You could have this in __init__.py

import foo
import bar
import baz

then, if you simply write import mypackage , it will also import mypackage.foo, mypackage.bar and mypackage.baz.

Comments
Thanks

to import all modules of a package at once is to list the modules you want imported in the package's __init__.py file like this

__all__ = ['foo', 'bar']

Then

from mypackage import *

will import foo and bar.

However if you need to import modules not known in advance (i.e. as plugins, sort of), you can use this:

import os, glob, imp

modules = {}

for path in glob.glob('mypackage/[!_]*.py'):
    name, ext = os.path.splitext(os.path.basename(path))
    modules[name] = imp.load_source(name, path)

>>> print modules
{'foo': <module 'foo' from 'mypackage\foo.py'>, 'bar': <module 'bar' from 'mypackage\bar.py'>}

Note how glob.glob('mypackage/[!_]*.py') will only return .PY files not starting with '_'.

Edited 7 Years Ago by pythopian: refactored

This article has been dead for over six months. Start a new discussion instead.