我有一个烧瓶应用程序,其本质上具有以下结构:
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.py
从web/api/api_impl.py
和from myapp import object
访问它。我已经能够在tool1
和tool2
导入web/
的多个地方使用myapp.py
和from common.tool1 import tool1_def
。
其他相关事实在myapp.py
中,有一个用于蓝图的import web
语句,并且app/__init__.py
和worker/__init__.py
为空。 web/__init__.py
包含路线的蓝图定义。
我可以使用gunicorn来运行该应用程序,但是没有问题,但是当我尝试使用python app/worker/worker.py
运行我的工作程序时,出现错误ModuleNotFoundError: No module named 'myapp'
。 worker.py
试图导入myapp.py
中定义的同一对象。
我只是不明白为什么我可以运行该应用程序并且它可以运行,但是当我尝试运行worker时却不能运行!在这种情况下,我绝对不能完全理解导入系统,而且我在网上阅读的所有内容似乎都无法完全阐明这一点。
答案 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
程序包,则它将首先在本地项目中查找。