从不同目录导入 python 个模块

Importing python modules from different directories

我有一个基本上具有以下结构的烧瓶应用程序:

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 中初始化了一个我在多个地方使用的重要对象,我可以使用 from myapp import objectcommon/tool1.pyweb/api/api_impl.py 访问它。我已经能够在 web/myapp.py 中的多个位置使用 tool1tool2 导入 from 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 中定义的同一对象。

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

您的工作导入意味着项目根目录是应用程序文件夹。因此,您需要从此文件夹中为您的工作人员提供午餐(或将其添加到 PYTHONPATH 环境变量)

python worker/worker.py 

或者

python -m worker.worker

此外,您的应用程序文件夹中的 __init__.py 应该被删除,因为应用程序不是包而是项目根目录。

我们经常用于开发和调试(但也适用于生产)的一种方法如下。您可以将其添加到每个(有问题的?)模块,或者如果您愿意,可以添加到所有模块。

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 模块,但在 site-packages 中也有一个 workers 包,这将首先在您的本地项目中查找。