0

I have a folder of modules (called modules) that currently contains 3 folders, each of which contain a package with an __init__.py file. What I would like to do is iterate through the modules folder, import each of the packages and execute its main() function.

I have attempted to do so like this:

import os

for dirnames in os.walk('modules'):
    for subdirname in dirnames:
        __import__("modules", subdirname)
        func = getattr(subdirname, "main", None)
        if func:
                func()

but it doesn't seem to be importing the modules, let alone executing the function.

I tried adding a manual call but it returned an error:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    rfm_433mhz.main()
NameError: name 'rfm_433mhz' is not defined

EDIT: I have added the changes as suggested but am still getting an AttributeError:

Module: rfm_433mhz
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    func = getattr(module, "main")
AttributeError: 'module' object has no attribute 'main'

For testing the __init__.py file has:

def main():
        print "hello"

1 Answers1

1

__import__ returns the imported module; it does not add it to the global namespace. Also subdirname is still the string object, not the module. The following would work:

for dirname in os.list('modules'):
    if os.isdir(os.path.join('modules', dirname)):
        module = getattr(__import__("modules." + dirname), dirname)
        func = getattr(module, "main", None)
        if func:
            func()

I'm using os.list() here; os.walk() would recurse over the directories, and each iteration returns a tuple of (dirname, directories, files) instead:

for root, dirs, files in os.walk('modules'):
    for dir in dirs:
        module = getattr(__import__("modules." + dir), dirname)
        func = getattr(module, "main", None)
        if func:
            func()
     dirs[:] = []  # don't recurse into directories.

Use importlib.import_module() instead to make this easier on yourself:

from importlib import import_module

for dirname in os.list('modules'):
    if os.isdir(os.path.join('modules', dirname)):
        module = import_module(dirname, 'modules')
        func = getattr(module, "main", None)
        if func:
            func()
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343