导入__init__.py中包中使用的模块

NoB*_*own 3 python

我有以下目录结构:

funniest/
    setup.py
    funniest/ 
          __init__.py
          ModuleA.py
          ModuleB.py
Run Code Online (Sandbox Code Playgroud)
# __init__.py
from numba import jit

from .ModuleA import ClassA
Run Code Online (Sandbox Code Playgroud)
# ModuleA.py
import funniest.ModuleB

class ClassA():
    pass
Run Code Online (Sandbox Code Playgroud)
# ModuleB.py
@jit
def f():
    pass
Run Code Online (Sandbox Code Playgroud)

但是,导入模块时,我收到错误消息:

>>> 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
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么会发生这种情况,因为当__init__.py首先执行时,它首先执行的是导入from numba import jit.那么,为什么jit没有定义,当涉及到的功能f在ModuleB?

kja*_*ier 6

您funniest/__init__.py输入的导入仅在您执行时导入import funniest,而不是在子模块内自动导入.所以ModuleB不知道jit.

什么,你需要做的,是移动from numba import jit的__init__.py到ModuleB.py.


Krz*_*iek 5

jit里面的名字是不知道的ModuleB。Python 导入不像 C/C++ 包含那样工作,它会推出代码来代替import. 一个新模块创建了一个新的命名空间,里面有一个映射——一个带有函数、类等的映射。

所以,当你做了import funniest,你创造了当前的命名空间的新映射条目,如:{..., funniest: {}, ...}。通过导入funniest,您导入jit和ClassA,所以从地方,当你输入的funniest模块,您可以访问这些地图:funniest: {jit: {..}, ClassA: {...}}。

在ModuleA您导入中ModuleB,因此ModuleA您有ModuleB:{...}内容为ModuleB. 但是在这里你看不到funniest地图 - 它在层次结构的其他级别。

在 中ModuleB,您看不到funniest和ClassA映射(命名空间 - 以及您喜欢的任何称呼;))。