从不同目录导入python模块
我有一个flask应用程序,基本上具有以下结构:从不同目录导入python模块,python,python-3.x,python-import,importerror,Python,Python 3.x,Python Import,Importerror,我有一个flask应用程序,基本上具有以下结构: 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/
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
使用myapp导入对象的访问它。我已经能够在web/
和myapp.py中的多个位置使用tool1
和tool2
从common.tool1导入工具1_def
导入
其他相关事实在myapp.py
中,蓝图有一个import-web
语句,app/\uuuuuuuuuuuuuuuuuuuuuuupy
和worker/\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuweb/_init__.py
包含路线的蓝图定义
我可以使用gunicorn运行应用程序,没有任何问题,但是当我尝试使用python app/worker/worker.py运行我的worker时,我得到了错误modulenofounderror:no module name'myapp'
。worker.py
正在尝试导入在myapp.py
中定义的相同对象
我只是不明白为什么我可以运行这个应用程序,它可以工作,但当我试图运行工人它没有!在这种情况下,我肯定没有完全理解导入系统,我在网上读到的所有内容似乎都没有完全阐明这一点。您的工作导入意味着项目根目录就是应用程序文件夹。因此,您需要从该文件夹(或将其添加到PYTHONPATH环境变量)中为工作人员提供午餐
或
此外,应删除应用程序文件夹中的\uuuu init\uuuuuuuuupy
,因为应用程序不是包而是项目根目录。工作导入意味着项目根目录就是应用程序文件夹。因此,您需要从该文件夹(或将其添加到PYTHONPATH环境变量)中为工作人员提供午餐
或
此外,应删除应用程序文件夹中的\uuuuuuu init\uuuuuuuuuuy.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
中的第一项
另一个优点是这些导入对您的项目是明确的。例如,如果您有一个要导入的本地工作者
模块,但在站点包
中也有一个工作者
包,这将首先查看您的本地项目。我们经常用于开发和调试的一种方法(但也适用于生产环境)如下。您可以将其添加到每个(有问题的?)模块或所有模块(如果您选择)
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
中的第一项
另一个优点是这些导入对您的项目是明确的。例如,如果您有一个要导入的本地工作者
模块,但在站点包
中也有一个工作者
包,这将首先查看您的本地项目。谢谢。我删除了init.py,它没有改变任何东西,我怀疑这是好的。setup.py位于app的父文件夹中,但它确实表示包是app.web和app.worker(现在我删除了init.py)。工作程序使用应用程序文件夹中的python-m worker.worker
成功运行,但未使用python worker/worker.py
成功运行。知道为什么吗?有一件事,当我运行setup.py时,从app文件夹中删除\uuuu init\uuuu.py
后,它再也找不到我的任何软件包了。我应该将setup.py移到应用程序文件夹中还是手动定义它们?您需要确定项目结构。如果你想让应用程序成为一个包,这很好,但是所有的导入都应该是这样的:import app.worker.worker还有其他更高级的方法,比如相对导入,但是根据我的经验,从根包向下导入是最好的做法。谢谢。我删除了init.py,它没有改变任何东西,我怀疑这是好的。setup.py位于app的父文件夹中,但它确实表示包是app.web和app.worker(现在我删除了init.py)。工作程序使用应用程序文件夹中的python-m worker.worker
成功运行,但未使用python worker/worker.py
成功运行。知道为什么吗?有一件事,当我运行setup.py时,从app文件夹中删除\uuuu init\uuuu.py
后,它再也找不到我的任何软件包了。我应该将setup.py移到应用程序文件夹中还是手动定义它们?您需要确定项目结构。如果您希望应用程序成为一个包,那么这很好,但是所有导入都应该是这样的:import app.worker.worker还有其他更高级的方法,比如相对导入,但根据我的经验,从根包向下导入是最佳做法。
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 ...