Reputation: 1410
I would like to dynamically create and import modules inside an inner __init__.py
file, if one or several of a set of indexed submodules doesn't exist.
I have a set of module layers, say;
top_module/
__init__.py
sub_module/
__init__.py
a1/
__init__.py
n1.py
b1/
__init__.py
b1.py
b2/
__init__.py
b2.py
b3/
__init__.py
b3.py
a2/
__init__.py
a2.py
b*/...
a*/...
Where the top_module/__init__.py
does a from .sub_module import *
.
From within the top_module/sub_module/__init__.py
, say I have several of these a*
folders that are just indexed iteratively. I know that I can do something like this to iterate importing over an index for those modules that exist;
from importlib import import_module
for a in range(some_max_a):
import_module(f'.a{a}', package='top_module.sub_module')
And that I can do something like this to just ignore modules that don't exist yet;
from importlib import import_module
for a in range(some_max_a):
try:
import_module(f'.a{a}', package='top_module.sub_module')
except ModuleNotFoundError:
pass
What I would like to be able to do is dynamically create and import these modules if they don't exist.
What I have so far is
from importlib import import_module
from sys import modules
from types import ModuleType
PKG = 'top_module.sub_module'
for a in range(some_max_a):
try:
import_module(f'.a{a}', package=PKG)
except ModuleNotFoundError:
modules[f'{PKG}.a{a}'] = ModuleType(f'{PKG}.a{a}')
for b in range(some_max_b):
modules[f'{PKG}.a{a}.b{b}'] = ModuleType(f'{PKG}.a{a}.b{b}')
def function_all_should_have(*args, **kwargs):
raise NotImplementedError
modules[f'{PKG}.a{a}.b{b}'].function_all_should_have = function_all_should_have
import_module(f'{PKG}.a{a}')
I've tried with and without the {PKG}
in the import_module
call and or the ModuleType
call.
If I import the created package, I can see that all the modules that I'm expecting this to create exist in the sys.modules
, but trying to access any of them with a call to something like top_module.sub_module.a3.b3.function_all_should_have()
yields an error along the lines of
AttributeError: module 'top_module.sub_module' has no attribute 'a3'.
Yet I can see that there is a top_module.sub_module.a3
module along with all the top_module.sub_module.a3.b*
modules.
I'm not really sure why the modules would be created and exist in sys.modules
but be unreachable after importing.
If there's no easy answer I could just go back to my second example and pass
if the modules don't exist, but I would still like to understand what's happening here. The only closest question I could find to this was dynamic module creation.
Upvotes: 0
Views: 83