1

I have the following folder structure of python modules:

allFunctions
    ├─ import_all.py
    ├─ __init__.py
    ├─ funcSetA
    ├─ __init__.py
    │   ├─ funcA1.py
    │   └─ funcA2.py
    └─ funcSetB
        ├─ __init__.py
        ├─ funcB1.py
        ├─ funcB2.py
        └─ funcB3.py

I want to import all the functions to be useable as funcA1(), or at worst allFunctions.funcA1(), but explicitly not as allFunctions.funcSetA.funcA1(). I also want to import the functions using the script import_all.py, not with the top level__init__.py (other levels are fine). I am not worried about namespace conflicts as the function names are very specific

I tried doing the following:

import allFunctions
from allFunctions import funcSetA as funcSetA
from funcSetA import funcA1

but obviously this doesn't work

I'm running python3.10

Mauvai
  • 461
  • 2
  • 5
  • 17
  • I think this might help (not sure though, for I read it very cursorily): https://stackoverflow.com/questions/3365740/how-to-import-all-submodules – Swifty Oct 28 '22 at 12:44
  • @Swifty its along the same lines but its not quite what I want to do – Mauvai Oct 28 '22 at 14:04
  • first you have to import `funcA1` inside `allFunctions/__init__.py` to get it later as `from allFunctions import funcA1`. And if you want to import it as `from funcSetA import funcA1` then first you have to import `funcA1` inside `funcSetA/__init__.py`. And you have it in link in first comment as `import script` and `__all__ = ['script1', 'script2', 'script3']` – furas Oct 28 '22 at 17:03
  • BTW: you have file `funcA1.py` but you would need also function `funcA1()` inside this file and import it as `from funcA1 import funcA1` (which means `from file funcA1.py import function funcA1()`). File `funcA1.py` can't be used as function `funcA1()` – furas Oct 28 '22 at 17:08

1 Answers1

0

Many stack overflow pages later I compiled an answer. I absolutely cannot recommend anyone does this, I had very specific reasons for doing things this way - but it does work. This code goes in the top level __init__.py (it might be possible to make a loader script like I originally wanted, I stopped trying. All __init__.py files in any folder other than the top level is completely blank (again, very specific reasons...)

import pkgutil
#import the packages

__all__ = []
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    modNameSplit = module_name.split(".")[-1]
    __all__.append(modNameSplit)
    _module = loader.find_module(module_name).load_module(module_name)
    globals()[modNameSplit] = _module

    
    #if functions exist within the module, this imports them
    module_dict = _module.__dict__
    try:
        to_import = _module.__all__
    except AttributeError:
        to_import = [name for name in module_dict if not name.startswith('_')]
    globals().update({name: module_dict[name] for name in to_import})
Mauvai
  • 461
  • 2
  • 5
  • 17