Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing modules used in a package in __init__.py

Tags:

python

I have the following directory structure:

funniest/
    setup.py
    funniest/ 
          __init__.py
          ModuleA.py
          ModuleB.py
# __init__.py
from numba import jit

from .ModuleA import ClassA
# ModuleA.py
import funniest.ModuleB

class ClassA():
    pass
# ModuleB.py
@jit
def f():
    pass

However, when importing the module, I get the error message:

>>> import funniest
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/domi89/Dropbox/Python_Projects/funniest/funniest  /__init__.py", line 2, in <module>
from .ModuleA import ClassA
File "/home/domi89/Dropbox/Python_Projects/funniest/funniest /ModuleA.py", line 1, in <module>
import funniest.ModuleB
File "/home/domi89/Dropbox/Python_Projects/funniest/funniest/ModuleB.py", line 1, in <module>
@jit
NameError: name 'jit' is not defined

I cannot understand why this happends, because when __init__.py get executed first, the first thing it does is importing from numba import jit. So why is jit not defined when it comes to function f in ModuleB?

like image 809
NoBackingDown Avatar asked Dec 19 '22 13:12

NoBackingDown


2 Answers

The imports you put in funniest/__init__.py are only imported when you do import funniest, not automatically inside submodules. So ModuleB doesn't know about jit.

What you need to do here is to move from numba import jit from __init__.py to ModuleB.py.

like image 140
kjaquier Avatar answered Dec 30 '22 06:12

kjaquier


The name jit is not known inside ModuleB. Python imports doesn't work like C/C++ includes that roll-out the code in place of the import. A new module creates a new namespace with a map inside - a map with functions, classes, etc.

So when you did import funniest, you created new map entry in the current namespace, like: {..., funniest: {}, ...}. By importing funniest, you imported jit and ClassA, so from the place when you imported the funniest module, you have access to such map: funniest: {jit: {..}, ClassA: {...}}.

In ModuleA you imported ModuleB, so in ModuleA you have new variable ModuleB:{...} with content of ModuleB. But here you don't see the funniest map - it is in other level in hierarchy.

And in ModuleB, you don't see funniest and ClassA maps (namespaces - and whatever you like to call it;)).

like image 37
Krzysiek Avatar answered Dec 30 '22 06:12

Krzysiek