1

Present situation:

  • I have a script: program.py.

  • I have a directory: /imports. Which contains an arbitrary amount of modules in subdirectories.

  • Python's package directory syntax is being used.

     __init__.py
     program.py
     /imports
         __init__.py
         /module a
             __init__.py
             other_files.py
         /module b
             __init__.py
             other
    

Intention:
  • program.py should import every subdirectory in /imports.
  • program.py needs object access to the modules. For example, imports['name'].Service().

Remark: I don't feel like illustrating my purpose or questioning the design choice. I'm using the above workaround. The problem is described below.

The existing code:

import os

modules = []
IMPORT_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'imports')
to_import = [name for name in os.listdir(IMPORT_PATH) if os.path.isdir(os.path.join(IMPORT_PATH, name))]
modules = [__import__('imports.' + x) for x in to_import]
print modules

Output:

[<module 'imports' from '/code/test/imports/__init__.pyc'>, <module 'imports' from '/code/test/imports/__init__.pyc'>]

Desired output:

[<module 'B' from '/code/test/imports/B'>, <module 'C' from '/code/test/imports/C'>]
smci
  • 32,567
  • 20
  • 113
  • 146
user193661
  • 879
  • 10
  • 29

1 Answers1

2

Problem identified: The fromlist=[] argument for __import__() is missing. See Why does Python's __import__ require fromlist? for elaboration.

Corrected example:

modules = {}
IMPORT_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'imports')
to_import = [name for name in os.listdir(IMPORT_PATH) if os.path.isdir(os.path.join(IMPORT_PATH, name))]
for x in to_import:
    modules[x] = __import__('imports.' + x, fromlist=['*'])

Output:

{'C': <module 'imports.C' from '/code/test/imports/C/__init__.pyc'>, 
'B': <module 'imports.B' from '/code/test/imports/B/__init__.pyc'>}

Achieved result:

  • Now modules[dir_name].Service() can be used in program.py.
Community
  • 1
  • 1
user193661
  • 879
  • 10
  • 29