我有一个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成为工作目录?
本质上,当您script.py直接执行时,它不知道它是的子模块的一部分src,也不知道命名的模块src可能在哪里。在python 2或3中就是这种情况。
src
如您所知,Python根据的内容查找模块sys.path。为了导入任何模块,它必须位于中列出的目录中sys.path,或者与您正在运行的脚本位于同一目录中。
sys.path
当您说时python src/scripts/script.py,请sys.path包含Project/src/scripts/(因为script.py位于此处),但不包含Project。由于Project不在路径中,因此src无法导入该目录()中的模块。
python src/scripts/script.py
Project/src/scripts/
Project
要解决此问题:
我假设您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,但是insrc中什么也不能导入script.py。
如果不是这种情况,并且script.py确实是的一部分src,则可以使用python的-m参数script.py作为src模块的一部分执行,如下所示:
-m
$ python -m src.scripts.script
因为您已经告诉python您正在运行哪个模块(src),所以它将位于路径中。因此,请script.py注意,它是的子模块src,然后可以从导入src。
在这种情况下,虽然小心-有可能创造一个圆形的进口,如果事情在src进口src.scripts.script。
src.scripts.script
作为这两种方法的替代,您可以sys.path直接在中修改script.py:
import sys sys.path.insert(0, '/path/to/Project') # location of src
尽管此方法有效,但通常不是我的偏好。它需要script.py确切地知道代码的布局方式,并且如果另一个python程序尝试导入,可能会导致导入混乱script.py。