我正在用一些基本的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'的模块
答案 0 :(得分:1)
您遇到No module named 'file2'
,因为您在包外面运行run.py
,当file1
导入file2
时,python找不到file2
,因为模块目录不在模块中搜索路径。
针对您的方案,file1
& file2
是2个模块,在同一个包中,对于这种情况,建议您使用relative import
,这是最佳做法。
from .file2 import B
class A(object):
pass
然后,python run.py
有效。
正如您所提到的,如果执行python p1/run.py
:
尝试相对导入而没有已知的父包
这是什么意思?
这是因为relative import
可以在包中的模块中得到支持。
您可能会说file1.py
在p1
个包中,为什么还会看到错误?
这是因为python使用__name__
来确定包中是否包含此模块,而不是它的位置。
按如下方式更改file1.py
:
print(__name__)
from .file2 import B
class A(object):
pass
接下来是输出:
p1.file1
文件1
对于python p1/run.py
,因为它在包中运行,python将无法知道它在包中,因此输出为file1
。
如果__name__
没有.
,python会认为它不在包中,因此相对导入失败。
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