这是树:
X
|_ setup.py
|_ X
|_ someFile.py
|_ __init__.py (empty)
|_ Y
|_ __init__.py (empty)
|_ anotherFile.py
运行
pip install -e .
之后,我可以在系统上的任何位置运行以下命令:import X
from X import someFile
from X.Y import anotherFile
但是我无法运行:
from X import Y
Y.anotherFile
-> Module X.Y has no attribute "anotherFile".
我可以通过用
__init__.py
填充较低级别的from X.Y import anotherFile
来解决此问题,但这似乎有些奇怪。这是为什么?我对python软件包的理解错误吗?
免责声明:以前可能有人问过这个问题,但是这个问题太笼统了,我很难找到合适的职位。
最佳答案
实际上很简单。对于from X import Y
,导入的模块是目录__init__.py
中的Y
文件,但不是所有其他文件。
但是我认为真正的问题是,为什么?
假设anotherFile
是您想要的唯一模块,因此可以通过anotherFile
导入from X.Y import anotherFile
。但是实际上您还导入了X
和Y
。尽管无法通过X
或Y
访问它们,但是如果使用import sys
和sys.modules.keys()
,则可以将这些模块视为X
和X.Y
。您可以通过Y
访问sys.modules["X.Y"].a # suppose there is
中的属性。这意味着目录__init__.py
下的Y
文件已执行。
好的,所以现在如果导入Y
或X
还将执行该程序包下的所有文件,您猜怎么着?是的,即使您只需要anotherFile
模块,也会执行所有文件,包括目录Y
下的目录X
。这些文件还会导入其他文件,依此类推...仅需一次导入,即可导入整个项目。