问题描述
我有一个 python 项目(我在 virtualenv 中运行),它具有以下结构:
I have a python project (which I run within a virtualenv) and that has the following structure:
Project
├───.git
├───venv
└───src
├───__init__.py
├───mymodules
│ ├───__init__.py
│ ├───module1.py
│ └───module2.py
└───scripts
├───__init__.py
└───script.py
脚本.py
import src.mymodules.module1
...
我在激活 venv 的情况下使用以下命令从项目目录运行项目:
I run the project with venv activated and from the Project directory using the following command:
(venv)$ python src/scripts/script.py
脚本运行但退出前出现以下错误:
The script runs but gives out the following error before exiting:
Traceback (most recent call last):
File "src/scripts/script.py", line 1, in <module>
import src.mymodules.module1
ImportError: No module named src.mymodules.module1
我尝试运行 python shell 并尝试从那里导入模块,它没有给出任何错误.我在 src 中的每个目录中都有 _ _init__.py .python 是否认为工作目录是 src/scripts?为什么会发生这种情况?如果是这种情况,我怎样才能使 src 成为工作目录?
I have tried running the python shell and trying to import the module from there and it gave no errors. I have _ _init__.py in every directory within src. Is python considering the working directory to be src/scripts? Why is that happening and how can I make src the working directory if that's the case?
推荐答案
本质上,当你直接执行 script.py
时,它并不知道它是 src 的子模块的一部分
,它也不知道名为 src
的模块可能在哪里.在 python 2 或 3 中都是这种情况.
Essentially, when you execute script.py
directly, it doesn't know that it's part of a submodule of src
, nor does it know where a module named src
might be. This is the case in either python 2 or 3.
如您所知,Python 根据 sys.path
.为了导入任何模块,它必须位于 sys.path
中列出的目录中,或者位于与您正在运行的脚本相同的目录中.
As you know, Python finds modules based on the contents of sys.path
. In order to import any module, it must either be located in a directory that's listed in sys.path
, or, in the same directory as the script that you're running.
当你说 python src/scripts/script.py
时,sys.path
包括 Project/src/scripts/
(因为那是script.py
所在的位置),而不是 Project
.由于 Project
不在路径中,因此无法导入该目录 (src
) 中的模块.
When you say python src/scripts/script.py
, sys.path
includes the Project/src/scripts/
(because that's where script.py
is located), but not Project
. Because Project
isn't in the path, the modules in that directory (src
) aren't able to be imported.
解决这个问题:
我假设您的 script.py
是您的 src
模块的入口点(例如,它可能是主程序).如果这是真的,那么您可以通过将 script.py
移动到与 src
相同的级别来修复它:
I'm assuming that your script.py
is an entry point for your src
module (for example, maybe it's the main program). If that's true, then you could fix it by moving script.py
up to the same level as src
:
Project
├───.git
├───venv
|───script.py <--- script.py moves up here
└───src
├───__init__.py
└───mymodules
├───__init__.py
├───module1.py
└───module2.py
这样script.py
可以自由地导入src
中的任何东西,而src
中的任何东西都不能导入script.py.
This way,
script.py
can freely import anything in src
, but nothing in src
can import script.py
.
如果不是这样,并且
script.py
确实是 src
的一部分,则可以使用 python 的 -m
参数来执行 script.py
作为一部分src
模块如下:
If that's not the case, and
script.py
really is a part of src
, you can use python's -m
argument to execute script.py
as part of the src
module like so:
$ python -m src.scripts.script
因为您已经告诉 python 您正在运行哪个模块 (
src
),所以它将在路径中.因此,script.py
会知道它是 src
的子模块,然后就可以从 src
导入.
Because you've told python which module you're running (
src
), it will be in the path. So, script.py
will be aware that it's a submodule of src
, and then will be able to import from src
.
但在这种情况下要小心 - 如果
src
中的某些内容导入 src.scripts.script
,则可能会创建循环导入.
Be careful in this situation though - there's potential to create a circular import if something in
src
imports src.scripts.script
.
作为这两种方法的替代方案,您可以直接在
script.py
中修改 sys.path
:
As an alternative to both of these approaches, you can modify the
sys.path
directly in script.py
:
import sys
sys.path.insert(0, '/path/to/Project') # location of src
虽然这可行,但通常不是我的偏好.它需要
script.py
准确地知道你的代码是如何布局的,并且如果另一个 python 程序试图导入 script.py
可能会导致导入混乱.
While this works, it's not usually my preference. It requires
script.py
to know exactly how your code is laid out, and may cause import confusion if another python program ever tries to import script.py
.
这篇关于Python 找不到我的模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!