Python无法找到我的模块

时间:2015-11-23 02:40:38

标签: python path packages

我有一个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
...

我使用以下命令从Venv激活项目目录运行项目:

(venv)$ python src/scripts/script.py

脚本运行但在退出之前发出以下错误:

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作为工作目录?

4 个答案:

答案 0 :(得分:18)

基本上,当你直接执行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.pysrc模块的入口点(例如,也许它是主程序)。如果这是真的,那么您可以通过将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作为{{1}的一部分像这样的模块:

src

因为你告诉python你正在运行哪个模块($ python -m src.scripts.script ),它将在路径中。因此,src会知道它是script.py的子模块,然后才能从src导入。

在这种情况下要小心 - 如果src导入src中的内容,则可能会创建循环导入。

作为这两种方法的替代方法,您可以直接在src.scripts.script修改sys.path

script.py

虽然这有效,但通常不是我的偏好。它需要import sys sys.path.insert(0, '/path/to/Project') # location of src 确切地知道你的代码是如何布局的,如果另一个python程序试图导入script.py,可能会导致导入混乱。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

另一种解决方案是创建文件名“ xxx(任何名称).pth”并写入项目目录(src的母亲目录)。将此文件放在“ / virtual_env / lib / pythonXX / site-packages /”中。这样,您无需在脚本中导入sys.path。

答案 3 :(得分:0)

如果在处理Pytestcoverage时遇到此问题。添加__init__.py文件可以解决大多数情况。