从不同目录导入python模块

时间:2019-10-30 23:11:51

标签: python python-3.x python-import importerror

我有一个烧瓶应用程序,其本质上具有以下结构:

app/
  __init__.py
  myapp.py
  common/
    tool1.py
    tool2.py
  web/
    __init__.py
    views.py
    api/
      api_impl.py
  worker/
    __init__.py
    worker.py
    tasks.py

我在myapp.py中初始化了一个我在多个地方使用的重要对象,并且可以使用common/tool1.pyweb/api/api_impl.pyfrom myapp import object访问它。我已经能够在tool1tool2导入web/的多个地方使用myapp.pyfrom common.tool1 import tool1_def

其他相关事实在myapp.py中,有一个用于蓝图的import web语句,并且app/__init__.pyworker/__init__.py为空。 web/__init__.py包含路线的蓝图定义。

我可以使用gunicorn来运行该应用程序,但是没有问题,但是当我尝试使用python app/worker/worker.py运行我的工作程序时,出现错误ModuleNotFoundError: No module named 'myapp'worker.py试图导入myapp.py中定义的同一对象。

我只是不明白为什么我可以运行该应用程序并且它可以运行,但是当我尝试运行worker时却不能运行!在这种情况下,我绝对不能完全理解导入系统,而且我在网上阅读的所有内容似乎都无法完全阐明这一点。

2 个答案:

答案 0 :(得分:1)

您的有效导入意味着项目根目录是app文件夹。因此,您需要在此文件夹中为您的工作人员午餐(或将其添加到PYTHONPATH环境变量中)

python worker/worker.py 

python -m worker.worker

此外,应删除您在app文件夹中的__init__.py,因为app不是软件包,而是项目根目录。

答案 1 :(得分:1)

下面是我们经常用于开发和调试(但也可以在生产中使用)的一种方法。您可以将其添加到每个(有问题的?)模块,或者您选择的所有模块中。

import os
import sys

# Add your project root to sys.path.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

from common import tool1
from common import tool2
from worker import worker
etc ...

在这里,您要将项目根目录添加到sys.path。执行导入时,Python首先从sys.path中查找您要导入的模块。因此,在这里,您要将项目根目录添加为sys.path中的第一项。

另一个优点是这些导入对您的项目是显式的。例如,如果您有要导入的本地workers模块,但在workers中有一个site-packages程序包,则它将首先在本地项目中查找。