[英]Python Submodule Importing Madness
I'm banging my head against the wall with some basic Python importing. 我通过一些基本的Python导入使我的头撞到了墙上。 I have simplified the problem as much as possible hoping I'd be able to expand this to a larger scale if I understand how this works
我已尽可能简化了该问题,希望如果我了解其工作原理,便可以将其扩展到更大的规模
Here is the dilemma - 这是两难的境地 -
run.py
from inside the submodule p1
works, but NOT when it's at the top level. 子模块
p1
内部的run.py
可以工作,但是在顶层时则不能。 Why? 为什么?
(version Python 3.6.3) (版本Python 3.6.3)
/sandbox
__init__.py
/p1
__init__.py
file1.py
run.py
run.py
/sandbox/p1/__init__.py /sandbox/p1/__init__.py
__all__ = ["file1", "file2"]
/sandbox/p1/file1.py /sandbox/p1/file1.py
from file2 import B
class A(object):
pass
/sandbox/p1/file2.py /sandbox/p1/file2.py
class B(object):
pass
/sandbox/p1/run.py /sandbox/p1/run.py
from file1 import A
a = A()
/sandbox/run.py /sandbox/run.py
from p1 import file1
a = file1.A()
Doing: 这样做:
python p1/run.py
(works fine) python p1/run.py
(工作正常)
python run.py
Traceback (most recent call last): File "run.py", line 2, in from p1 import file1 File ".../sandbox/p1/file1.py", line 1, in from file2 import B ModuleNotFoundError: No module named 'file2'
追溯(最近一次通话):文件“ run.py”,第2行,来自p1导入file1文件“ ... / sandbox / p1 / file1.py”,第1行,来自file2导入B ModuleNotFoundError:无模块名为“ file2”
You encountered No module named 'file2'
because you run run.py
outside a package, when file1
import file2
, python cannot find file2
as the module directory not in module search path. 您
No module named 'file2'
遇到No module named 'file2'
因为您在run.py
外部运行run.py
,当file1
导入file2
,python找不到file2
作为不在模块搜索路径中的模块目录。
For your scenario, file1
& file2
are 2 modules which in the same package, for this situation, suggest you use relative import
, this is the best practice. 对于您的情况,
file1
和file2
是2个模块,它们在同一软件包中,对于这种情况,建议您使用relative import
,这是最佳实践。
from .file2 import B
class A(object):
pass
Then, python run.py
works. 然后,
python run.py
工作。
As you mentioned you will see next if execute python p1/run.py
: 如您所述,如果执行
python p1/run.py
您将看到下一个:
attempted relative import with no known parent package
尝试相对导入,但没有已知的父程序包
What does it mean? 这是什么意思?
This because relative import
can just be supported in the module which in package. 这是因为
relative import
只能在包中的模块中受支持。
You may say file1.py
is in package p1
, why still see the error? 您可能会说
file1.py
在软件包p1
,为什么仍然看到错误?
This is because python use __name__
to determine if this module in package or not, not by the position of it. 这是因为python使用
__name__
来确定此模块是否在包中,而不是通过其位置来确定。
Change file1.py
as follows: 如下更改
file1.py
:
print(__name__)
from .file2 import B
class A(object):
pass
Next is the output: 接下来是输出:
p1.file1
p1.file1
file1
文件1
For python p1/run.py
, because it runs in the package, python will fail to know it is in a package, so output is file1
. 对于
python p1/run.py
,因为它在软件包中运行,所以python将无法知道它在软件包中,因此输出为file1
。
If __name__
does not has .
如果
__name__
没有.
, python will think it's not in package, so relative import failure. ,python会认为它不在软件包中,因此相对导入失败。
python p1/run.py
, eg unittest your package? python p1/run.py
,例如,对程序包进行单元测试,该怎么办? Use python -m p1.run
, this should works to execute top script which inside a package. 使用
python -m p1.run
,这应该可以执行包中的顶级脚本。
Python makes it intentionally difficult to mix scripts in a modules. Python使得故意在模块中混合脚本变得困难。 The way this can be handled is like this:
可以这样处理:
/project
/scripts
run.py
/sandbox
__init__.py
/p1
__init__.py
file1.py
file2.py
/project/sandbox/p1/file1.py /project/sandbox/p1/file1.py
from .file2 import B
class A(object):
pass
/project/sandbox/p1/file2.py /project/sandbox/p1/file2.py
class B(object):
pass
/project/scripts/run.py /project/scripts/run.py
from sandbox.p1.file1 import A
a = A()
I make sure that the path to /project
is in a .pth
file in the site-packages of the virtual environment I want to use it from. 我确保
/project
的路径位于我要在其中使用的虚拟环境的站点包中的.pth
文件中。
If you use conda, you can use conda develop
如果使用conda,则可以使用
conda develop
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.