Python无法找到我的模块

Cra*_*ony 27 python packages path

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

Project
????.git
????venv
????src
    ????__init__.py
    ????mymodules
    ?   ????__init__.py
    ?   ????module1.py
    ?   ????module2.py
    ????scripts
        ????__init__.py
        ????script.py
Run Code Online (Sandbox Code Playgroud)

script.py

import src.mymodules.module1
...
Run Code Online (Sandbox Code Playgroud)

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

(venv)$ python src/scripts/script.py
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

我已经尝试运行python shell并尝试从那里导入模块,它没有给出任何错误.我在src中的每个目录中都有_ _init__.py.python是否将工作目录视为src/scripts?为什么会发生这种情况?如果是这种情况,如何将src作为工作目录?

Set*_*eth 21

本质上,当你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.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
Run Code Online (Sandbox Code Playgroud)

这样,script.py可以自由导入任何内容src,但没有任何东西src可以导入script.py.

如果不是这样,并且script.py真的是其中的一部分src,您可以使用python的-m参数script.py作为src模块的一部分执行,如下所示:

$ python -m src.scripts.script
Run Code Online (Sandbox Code Playgroud)

因为你告诉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 
Run Code Online (Sandbox Code Playgroud)

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


小智 6

Project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80.git\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80venv\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80src\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80__init__.py\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80mymodules\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80__init__.py\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80module1.py\n    \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80module2.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80scripts\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80__init__.py\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80script.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,您可以在 script.py 中像下面这样导入

\n\n
import os\nimport sys\nsys.path.append(os.path.join(os.path.dirname(__file__),'../../'))\nimport src.mymodules.module1\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
e.g :\npython script.py\npython /path to folder/script.py\n
Run Code Online (Sandbox Code Playgroud)\n