小编典典

Python找不到我的模块

python

我有一个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激活运行项目,并从Project目录中运行该项目:

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


阅读 191

收藏
2021-01-20

共1个答案

小编典典

本质上,当您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,但是insrc中什么也不能导入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


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

import sys
sys.path.insert(0, '/path/to/Project') # location of src

尽管此方法有效,但通常不是我的偏好。它需要script.py确切地知道代码的布局方式,并且如果另一个python程序尝试导入,可能会导致导入混乱script.py

2021-01-20