-1

I am develepong a blender addon which has several submodules

- A/__init__.py
  |
  |- B/__init__.py

In A/init.py I can do import A.B to import the content of submodule B, but I would like to be able to import automatically this files. Is there any way to achieve that?

The idea is that my addon is used to implement several glTF extensions. Each extension is in its own submodule and the glTF exporter expects me to return some classes, one for each extension.

Instead of importing manually each extension and adding the class to the list of extensions, I want that to happen automatically

instead of

from A.B import B_extension

glTF2ExportUserExtensions = [A.B.B_extension]

I want something like

# A.submodules returns all the submodules and extension() returns the extension class. Im assuming each submodule have an extension() function
glTF2ExportUserExtensions = [A.submodules.extension()]

I need to return a list of classes

jjcasmar
  • 1,387
  • 1
  • 18
  • 30
  • 1
    What do you mean by automatically? – JE_Muc Jan 25 '21 at 10:16
  • That I dont have to do `import A.B` but it is automatically imported when in blender I activate the addon. – jjcasmar Jan 25 '21 at 10:18
  • Then you should either provide more information about the module structure or read some tutorials about the topic. F.i. `init.py` should be called `__init__.py` instead. Also it is not clear, if `A` is part of the module or the submodule. Is there any module at an even higher level? **Where** exactly do you want to import the submodule? And **what do you mean by automatically?** Python can't guess what you want to import, you have to specify the imports at least in one place. So what is automatically? – JE_Muc Jan 25 '21 at 10:23
  • 1
    You are right, files are `__init__.py`, that was a typo. I have done some edits in the question. Blender is importing A module. Now I want A to be able to import B, which is a subdirectory of A containing another `__init__.py` file. I was thiking on somehow iterating on subdirectories of A – jjcasmar Jan 25 '21 at 10:28

2 Answers2

0

Ok, I guess I understand what you want to do.

So to import several submodules under the same "submodule-name" submodules, import them in a separate file submodules.py at the same level as A/__init__.py:

from .B import B_extension as extension
from .C import C_extension as someothername

And in A/__init__.py add:

from . import submodules

Now if you import A with

import A

you can access the submodules with A.submodules.extension, A.submodules.someothername, etc...

If you want to access the submodules functions/classes/etc. directly from submodules, such as A.submodules.extension(), your submodules.py files has to look like:

from .B.B_extension import extension, anotherBmethod, SomeBClass
from .C.C_extension import Cextension, anotherCmethod, SomeCClass

If you want to have a fully automatic import, use pkgutil (credit goes to this answer), even though I strongly object importing all submodules automatically. Explicit is better than implicit. You never know what happens when you change a single line in a submodule, without testing all imports when doing it implicitly... Add this to A/__init__.py:

import pkgutil

__all__ = []
for loader, module_name, is_pkg in  pkgutil.walk_packages(__path__):
    __all__.append(module_name)
    _module = loader.find_module(module_name).load_module(module_name)
    globals()[module_name] = _module
JE_Muc
  • 5,403
  • 2
  • 26
  • 41
  • Well, this is not automatic. I have to create a submodules file with all the imports. Can't I have python to look into subdirectories of current file (`A/__init__.py`) and automatically call a function on files matching a pattern (`A/B/__init__.py`) – jjcasmar Jan 25 '21 at 10:44
  • I'd definetely avoid this. You never know what's going to happen if you change a single line when you do something like this. Just take a look at the second line of `import this` – JE_Muc Jan 25 '21 at 10:47
0

You can import things from an essential file that you have the imports on.

Example of ./import_file.py

import example
import ...

You can use "*" to import everything from the import file, or you can import something specific.

Example of ./main_file.py

from import_file import *
from import_file import example
BenitzCoding
  • 299
  • 1
  • 16