从子目录导入和在子目录内导入时如何解决冲突的导入要求?
How to resolve conflicting import requirements when importing both from and within a subdirectory?
我有一个结构如下的项目:
./script.py
./modules/__init__.py
./modules/mod1.py
./modules/mod2.py
我需要在 mod1.py
中导入 mod2
,在 script.py
中导入 mod1
和 mod2
。为了便于测试,有时我也想 运行 mod1.py
文件作为脚本(使用 if __name__== "__main__":
)。但是,我正在观察以下内容:
- 在
script.py
中,我包括from modules import mod1
和from modules import mod2
。
- 如果我在
mod1.py
中包含 import mod2
,我可以 运行 mod1.py
...
- ...但是如果我尝试 运行
script.py
,我会得到 ModuleNotFoundError: no module named 'mod2'
。我可以修改 mod1.py
改为使用 from modules import mod2
,然后 script.py
运行s...
- ...但是如果我尝试 运行 只是
mod1.py
,我会得到 ModuleNotFoundError: no module named 'modules'
.
我搜索了该站点,发现了几个仅解决在目录中导入和从子目录中导入的问题,但未能找到任何解决两者之间冲突要求的方法。我错过了什么?
编辑:我 运行 通过 Spyder 的 IPython 控制台管理我的所有项目,因此适用于此工作流的解决方案会格外有用。
使用绝对导入:
from modules import mod1
from modules import mod2
和运行根目录中的所有内容使用-m option:
python -m script
python -m modules.mod1
python -m modules.mod2
@Piotr Praszmo 的回答有效。基于这个答案,我发现对于 运行 Spyder 脚本的特定情况,在任何地方都使用绝对导入,然后将 runfile
命令中的工作目录更改为根目录解决了我的问题:
runfile('./modules/mod1.py', wdir='./')
我有一个结构如下的项目:
./script.py
./modules/__init__.py
./modules/mod1.py
./modules/mod2.py
我需要在 mod1.py
中导入 mod2
,在 script.py
中导入 mod1
和 mod2
。为了便于测试,有时我也想 运行 mod1.py
文件作为脚本(使用 if __name__== "__main__":
)。但是,我正在观察以下内容:
- 在
script.py
中,我包括from modules import mod1
和from modules import mod2
。 - 如果我在
mod1.py
中包含import mod2
,我可以 运行mod1.py
... - ...但是如果我尝试 运行
script.py
,我会得到ModuleNotFoundError: no module named 'mod2'
。我可以修改mod1.py
改为使用from modules import mod2
,然后script.py
运行s... - ...但是如果我尝试 运行 只是
mod1.py
,我会得到ModuleNotFoundError: no module named 'modules'
.
我搜索了该站点,发现了几个仅解决在目录中导入和从子目录中导入的问题,但未能找到任何解决两者之间冲突要求的方法。我错过了什么?
编辑:我 运行 通过 Spyder 的 IPython 控制台管理我的所有项目,因此适用于此工作流的解决方案会格外有用。
使用绝对导入:
from modules import mod1
from modules import mod2
和运行根目录中的所有内容使用-m option:
python -m script
python -m modules.mod1
python -m modules.mod2
@Piotr Praszmo 的回答有效。基于这个答案,我发现对于 运行 Spyder 脚本的特定情况,在任何地方都使用绝对导入,然后将 runfile
命令中的工作目录更改为根目录解决了我的问题:
runfile('./modules/mod1.py', wdir='./')