Python无法找到我的模块

问题描述 投票:24回答:3

我有一个python项目(我在virtualenv中运行),它具有以下结构:

Project
├───.git
├───venv
└───src
    ├───__init__.py
    ├───mymodules
    │   ├───__init__.py
    │   ├───module1.py
    │   └───module2.py
    └───scripts
        ├───__init__.py
        └───script.py

script.朋友

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

python path packages
3个回答
18
投票

基本上,当你直接执行script.py时,它不知道它是src的子模块的一部分,也不知道名为src的模块可能在哪里。这是python 2或3中的情况。

如您所知,Python根据sys.path的内容查找模块。要导入任何模块,它必须位于sys.path中列出的目录中,或者与您正在运行的脚本位于同一目录中。

当你说python src/scripts/script.pysys.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,则有可能创建循环导入。


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

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

虽然这有效,但通常不是我的偏好。它需要script.py确切地知道你的代码是如何布局的,如果另一个python程序试图导入script.py,可能会导致导入混乱。


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

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.