0

我有一个烧瓶应用程序,其结构基本上如下:

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 objecttool1tool2web/myapp.pyfrom common.tool1 import tool1_def

其他相关事实在蓝图上myapp.py有一个声明,并且是空的。包含路线的蓝图定义。import webapp/__init__.pyworker/__init__.pyweb/__init__.py

我可以毫无问题地使用 gunicorn 运行该应用程序,但是当我尝试使用我的 worker 运行时,python app/worker/worker.py我得到了错误ModuleNotFoundError: No module named 'myapp'worker.py正在尝试导入 中定义的相同对象myapp.py

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

4

2 回答 2

1

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

python worker/worker.py 

或者

python -m worker.worker

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

于 2019-10-31T00:25:32.343 回答
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要导入的本地模块,但在 中也有一个workerssite-packages,这将首先在您的本地项目中查找。

于 2019-10-31T08:40:38.583 回答