Python子模块导入疯狂

时间:2018-03-06 11:04:45

标签: python import git-submodules

我正在用一些基本的Python导入攻击我的头。我已经尽可能地简化了这个问题,希望如果我能理解它是如何工作的话,我可以将它扩展到更大的范围

这就是困境 -
来自子模块bazel build //tensorflow/contrib/android:libtensorflow_inference.so ...内部的run.py可以正常工作,但不是在它位于顶层时。为什么呢?

(Python 3.6.3版)

结构:

p1

/沙箱/ P1 / __初始化__。PY

/sandbox
    __init__.py
    /p1
        __init__.py
        file1.py
        run.py
    run.py

/sandbox/p1/file1.py

__all__ = ["file1", "file2"]

/sandbox/p1/file2.py

from file2 import B
class A(object):
    pass

/sandbox/p1/run.py

class B(object):
    pass

/sandbox/run.py

from file1 import A
a = A()

这样做的:

from p1 import file1 a = file1.A() (工作正常)
python p1/run.py

  

追踪(最近一次通话):     文件“run.py”,第2行,in       来自p1 import file1     文件“... / sandbox / p1 / file1.py”,第1行,in       来自file2导入B.   ModuleNotFoundError:没有名为'file2'的模块

2 个答案:

答案 0 :(得分:1)

(I)没有名为' file2'

的模块

您遇到No module named 'file2',因为您在包外面运行run.py,当file1导入file2时,python找不到file2,因为模块目录不在模块中搜索路径。

针对您的方案,file1& file2是2个模块,在同一个包中,对于这种情况,建议您使用relative import,这是最佳做法。

file1.py

from .file2 import B
class A(object):
    pass

然后,python run.py有效。

(II)尝试相对导入而没有已知的父包

正如您所提到的,如果执行python p1/run.py

,您会看到下一步
  

尝试相对导入而没有已知的父包

这是什么意思?

这是因为relative import可以在包中的模块中得到支持。

您可能会说file1.pyp1个包中,为什么还会看到错误?

这是因为python使用__name__来确定包中是否包含此模块,而不是它的位置。

按如下方式更改file1.py

print(__name__)
from .file2 import B
class A(object):
    pass

接下来是输出:

python run.py

  

p1.file1

python p1 / run.py

  

文件1

对于python p1/run.py,因为它在包中运行,python将无法知道它在包中,因此输出为file1

如果__name__没有.,python会认为它不在包中,因此相对导入失败。

(III)最后,如果你真的想要执行python p1/run.py,例如, unittest你的包裹?

使用python -m p1.run,这应该可以在包内执行顶级脚本。

答案 1 :(得分:0)

Python使得在模块中混合脚本变得有意。可以这样处理的方式如下:

/project
    /scripts
        run.py
    /sandbox
        __init__.py
        /p1
            __init__.py
            file1.py
            file2.py

<强> /project/sandbox/p1/file1.py

from .file2 import B
class A(object):
    pass

<强> /project/sandbox/p1/file2.py

class B(object):
    pass

<强> /project/scripts/run.py

from sandbox.p1.file1 import A
a = A()

我确保/project的路径位于我要使用的虚拟环境的site-packages中的.pth文件中。

康达

如果您使用conda,则可以使用conda develop