Python 找不到我的模块
Python can't find my module
我有一个 python 项目(我在 virtualenv 中 运行)并且具有以下结构:
Project
├───.git
├───venv
└───src
├───__init__.py
├───mymodules
│ ├───__init__.py
│ ├───module1.py
│ └───module2.py
└───scripts
├───__init__.py
└───script.py
script.py
import src.mymodules.module1
...
I 运行 激活了 venv 的项目,并从项目目录中使用以下命令:
(venv)$ python src/scripts/script.py
脚本 运行s 但在退出前出现以下错误:
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 成为工作目录?
本质上,当你直接执行 script.py
时,它不知道它是 src
的子模块的一部分,也不知道名为 src
的模块可能在哪里. python 2 或 3 都是这种情况。
如您所知,Python 根据 sys.path
的内容查找模块。为了导入任何模块,它必须位于 sys.path
中列出的目录中,或者与您正在使用的脚本位于同一目录中 运行。
当您说 python src/scripts/script.py
时,sys.path
包括 Project/src/scripts/
(因为那是 script.py
所在的位置),但不包括 Project
。因为 Project
不在路径中,所以无法导入该目录 (src
) 中的模块。
解决这个问题:
我假设您的 script.py
是 src
模块的入口点(例如,它可能是主程序)。如果这是真的,那么您可以通过将 script.py
移动到与 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
。
如果不是这样,并且script.py
确实是src
的一部分,你可以使用python的-m
参数来执行script.py
作为 src
模块的一部分,像这样:
$ python -m src.scripts.script
因为您已经告诉 python 您是哪个模块 运行 (src
),所以它将在路径中。因此,script.py
将意识到它是 src
的子模块,然后将能够从 src
导入。
不过在这种情况下要小心 - 如果 src
中的某些内容导入 src.scripts.script
,则可能会创建循环导入。
作为这两种方法的替代方法,您可以直接在 script.py
中修改 sys.path
:
import sys
sys.path.insert(0, '/path/to/Project') # location of src
虽然这可行,但我通常不喜欢它。它需要 script.py
准确地知道您的代码是如何布局的,并且如果另一个 python 程序试图导入 script.py
可能会导致导入混乱。
Project
├───.git
├───venv
└───src
├───__init__.py
├───mymodules
│ ├───__init__.py
│ ├───module1.py
│ └───module2.py
└───scripts
├───__init__.py
└───script.py
或者,您可以在 script.py
中导入如下内容
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__),'../../'))
import src.mymodules.module1
现在您可以从任何位置 运行 script.py 文件。
e.g :
python script.py
python /path to folder/script.py
另一个解决方案是创建文件 some_file.pth
并写入您的项目目录(您的 src 的母目录)。将此文件放在 /virtual_env/lib/pythonXX/site-packages/
中。这样,您就不需要在脚本中导入sys.path
。
如果您在处理 Pytest
或 coverage
时遇到此问题。添加 __init__.py
文件解决了大多数情况。
我有一个 python 项目(我在 virtualenv 中 运行)并且具有以下结构:
Project
├───.git
├───venv
└───src
├───__init__.py
├───mymodules
│ ├───__init__.py
│ ├───module1.py
│ └───module2.py
└───scripts
├───__init__.py
└───script.py
script.py
import src.mymodules.module1
...
I 运行 激活了 venv 的项目,并从项目目录中使用以下命令:
(venv)$ python src/scripts/script.py
脚本 运行s 但在退出前出现以下错误:
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 成为工作目录?
本质上,当你直接执行 script.py
时,它不知道它是 src
的子模块的一部分,也不知道名为 src
的模块可能在哪里. python 2 或 3 都是这种情况。
如您所知,Python 根据 sys.path
的内容查找模块。为了导入任何模块,它必须位于 sys.path
中列出的目录中,或者与您正在使用的脚本位于同一目录中 运行。
当您说 python src/scripts/script.py
时,sys.path
包括 Project/src/scripts/
(因为那是 script.py
所在的位置),但不包括 Project
。因为 Project
不在路径中,所以无法导入该目录 (src
) 中的模块。
解决这个问题:
我假设您的 script.py
是 src
模块的入口点(例如,它可能是主程序)。如果这是真的,那么您可以通过将 script.py
移动到与 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
。
如果不是这样,并且script.py
确实是src
的一部分,你可以使用python的-m
参数来执行script.py
作为 src
模块的一部分,像这样:
$ python -m src.scripts.script
因为您已经告诉 python 您是哪个模块 运行 (src
),所以它将在路径中。因此,script.py
将意识到它是 src
的子模块,然后将能够从 src
导入。
不过在这种情况下要小心 - 如果 src
中的某些内容导入 src.scripts.script
,则可能会创建循环导入。
作为这两种方法的替代方法,您可以直接在 script.py
中修改 sys.path
:
import sys
sys.path.insert(0, '/path/to/Project') # location of src
虽然这可行,但我通常不喜欢它。它需要 script.py
准确地知道您的代码是如何布局的,并且如果另一个 python 程序试图导入 script.py
可能会导致导入混乱。
Project
├───.git
├───venv
└───src
├───__init__.py
├───mymodules
│ ├───__init__.py
│ ├───module1.py
│ └───module2.py
└───scripts
├───__init__.py
└───script.py
或者,您可以在 script.py
中导入如下内容import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__),'../../'))
import src.mymodules.module1
现在您可以从任何位置 运行 script.py 文件。
e.g :
python script.py
python /path to folder/script.py
另一个解决方案是创建文件 some_file.pth
并写入您的项目目录(您的 src 的母目录)。将此文件放在 /virtual_env/lib/pythonXX/site-packages/
中。这样,您就不需要在脚本中导入sys.path
。
如果您在处理 Pytest
或 coverage
时遇到此问题。添加 __init__.py
文件解决了大多数情况。