Python 找不到我的模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33862963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:07:24  来源:igfitidea点击:

Python can't find my module

pythonpathpackages

提问by CrazyJony

I have a python project (which I run within a virtualenv) and that has the following structure:

我有一个 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 run the project with venv activated and from the Project directory using the following command:

我在 venv 激活的情况下运行项目,并使用以下命令从项目目录运行:

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

The script runs but gives out the following error before exiting:

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

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

I have tried running the python shell and trying to import the module from there and it gave no errors. I have _ _init__.py in every directory within src. Is python considering the working directory to be src/scripts? Why is that happening and how can I make src the working directory if that's the case?

我试过运行 python shell 并尝试从那里导入模块,但没有出错。我在 src 的每个目录中都有 _ _init__.py。python 是否考虑将工作目录设为 src/scripts?为什么会发生这种情况,如果是这种情况,我如何使 src 成为工作目录?

采纳答案by Seth

Essentially, when you execute script.pydirectly, it doesn't know that it's part of a submodule of src, nor does it know where a module named srcmight be. This is the case in either python 2 or 3.

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

As you know, Python finds modules based on the contents of sys.path. In order to import any module, it must either be located in a directory that's listed in sys.path, or, in the same directory as the script that you're running.

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

When you say python src/scripts/script.py, sys.pathincludes the Project/src/scripts/(because that's where script.pyis located), but not Project. Because Projectisn't in the path, the modules in that directory (src) aren't able to be imported.

当您说python src/scripts/script.py,sys.path包括Project/src/scripts/(因为那script.py是位于何处),但不包括Project。由于Project不在路径中,因此src无法导入该目录 ( ) 中的模块。

To fix this:

要解决此问题:

I'm assuming that your script.pyis an entry point for your srcmodule (for example, maybe it's the main program). If that's true, then you could fix it by moving script.pyup to the same level as 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

This way, script.pycan freely import anything in src, but nothing in srccan import script.py.

通过这种方式,script.py可以自由导入任何东西src,但没有什么src可以导入script.py

If that's not the case, and script.pyreally is a part of src, you can use python's -margument to execute script.pyas part of the srcmodule like so:

如果情况并非如此,并且script.py确实是 的一部分src,则可以使用 python 的-m参数script.py作为src模块的一部分执行,如下所示:

$ python -m src.scripts.script

Because you've told python which module you're running (src), it will be in the path. So, script.pywill be aware that it's a submodule of src, and then will be able to import from src.

因为您已经告诉 python 您正在运行哪个模块 ( src),它将在路径中。因此,script.py将意识到它是 的子模块src,然后将能够从 导入src

Be careful in this situation though - there's potential to create a circular import if something in srcimports src.scripts.script.

在这种情况下,虽然小心-有可能创造一个圆形的进口,如果事情在src进口src.scripts.script



As an alternative to both of these approaches, you can modify the sys.pathdirectly in script.py:

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

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

While this works, it's not usually my preference. It requires script.pyto know exactly how your code is laid out, and may cause import confusion if another python program ever tries to import script.py.

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

回答by parthiban

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

Alternatively you can import like the following in your script.py

或者,您可以在 script.py 中导入如下内容

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__),'../../'))
import src.mymodules.module1

Now you can run script.py file from any location.

现在您可以从任何位置运行 script.py 文件。

e.g :
python script.py
python /path to folder/script.py

回答by Guiliang Liu

Another solution is creating file name 'xxx(any name).pth' and write your project dir (mother dir of your src). Put this file in '/virtual_env/lib/pythonXX/site-packages/'. In this way, you don't need to import sys.path in your script.

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

回答by azzamsa

If you face this problem when dealing with Pytestor coverage. Adding __init__.pyfile solve most of the cases.

如果您在处理Pytest或时遇到此问题coverage。添加__init__.py文件解决了大多数情况。