【问题标题】:How to import a package module from inside a Flask route?如何从 Flask 路由中导入包模块?
【发布时间】:2014-07-14 17:29:26
【问题描述】:

我正在将我编写的应用程序迁移到标准 Python 包格式。由于我将应用程序的模块划分为多个目录,因此我过去常常通过将它们各自的路径插入到 sys.path 来导入这些模块,但这不再是一种选择,因为这些模块还从包内部导入它们各自的依赖项。

我正在尝试将一组模块从 Flask 中的路由 (@app.route) 加载到单独的文件中。

@app.route("/interface")
def interface():
    moduleName = "Olympus.modules.%s.%s" % (category, module)
    print "Importing:", moduleName
    importedModule = __import__(moduleName)

(我已经删除了这个函数中多余的代码。)然而,这个函数只产生 ImportErrors,告诉我“没有名为的模块”。每个(子)目录中都有__init__.py 文件,这些模块可以毫不费力地导入到其他地方。从包含目录的__init__.py 导入模块会导致模块及其兄弟姐妹(例如,同一category 中的所有脚本)可以从脚本中访问,但这需要我对 init 文件中的所有模块进行硬编码.

路由位于由应用程序的 init 文件导入的 Flask (http://flask.pocoo.org/docs/patterns/packages/) 建议的单独文件中。当打印__name__ 时,它会产生正确的打包名称。这些模块也可以在文件顶部单独导入,不会产生不良影响。 在函数内部按照建议的here 打印pkgutils.itermodules 会产生一个空列表。

我做错了什么?如何将这些模块导入到这个 Flask 路由中?

编辑:有问题的代码可以在这里找到:https://github.com/HAN-Olympus/Olympus/tree/master/webapp 编辑:这是目录结构,我对它进行了一些修剪,但它仍然相当广泛。

.
├── Olympus
│   ├──__init__.py
│   ├── core
│   │   ├── Core.py
│   │   ├── __init__.py
│   │   ├── ModuleLoader.py
│   │   ├── Worker.py
│   ├── createMongoDatabase.js
│   ├── default.conf
│   ├── __init__.py
│   ├── lib
│   │   ├── Article.py
│   │   ├── Chemical.py
│   │   ├── Collection.py
│   │   ├── Config.py
│   │   ├── Controls.py
│   │   ├── Gene.py
│   │   ├── __init__.py
│   │   ├── ...
│   │   ├── TOXNETResult.py
│   ├── modules
│   │   ├── acquisition
│   │   │   ├── AcquisitionModule.py
│   │   │   ├── GeneOntology.py
│   │   │   ├── __init__.py
│   │   │   ├── PubMed.py
│   │   │   ├── TOXNET.py
│   │   │   ├── UniProt.py
│   │   │   ├── WormBase.py
│   │   ├── __init__.py
│   │   ├── interface
│   │   │   ├── __init__.py
│   │   │   ├── InterfaceModule.py
│   │   │   ├── LaTeX.py
│   │   │   ├── PlainHTML.py
│   │   │   ├── StyledHTML.py
│   │   ├── interpretation
│   │   │   ├── __init__.py
│   │   │   ├── InterpretationModule.py
│   │   │   ├── Sort.py
│   │   │   ├── Tail.py
│   │   └── visualization
│   │       ├── FancyTable.py
│   │       ├── __init__.py
│   │       ├── Table.py
│   │       ├── VisualizationModule.py
│   ├── olympus.conf
│   ├── README.md
│   ├── requirements.txt
│   └── webapp
│       ├── __init__.py
│       ├── routes.py
│       ├── start.py
│       ├── svglib.py
│       └── templates
│           ├── ...

【问题讨论】:

  • 您确定可以在不使用__import__ 的情况下直接导入模块吗?在导入方面,Flask 路由没有什么特别之处。
  • 将导入放在 routes.py 文件的顶部(路由所在的位置)达到预期的效果,但是,我希望动态加载模块,当你不会发生这种情况导入路由文件。
  • 我的意思是在路由中直接导入模块。
  • 我已经用import Project.modules.category.module 试过这个。这会产生 ImportError: No module named modules.category.module 。我应该注意到我已经通过在 init 文件中动态加载模块来缓解这个问题,但我仍然觉得我无法在路由中导入包模块感到奇怪。
  • 听起来你在某处有一个 Projects.pyProjectselse 来屏蔽导入。 import Projects; print Projects.__file__ 告诉你什么是进口的?

标签: python import flask package


【解决方案1】:

将所有模块维护为标准模块

保持简单并安装您的模块以导入到您的 Flask 环境中。

完成所有模块(包括setup.py)

要使您的模块可安装,它们必须包含setup.py 安装脚本。检查文档,如何做到这一点。

将模块安装到 Flask 应用中

从您的 Flask 应用程序目录中,您可以通过以下方式安装其他模块:

$ pip install ../other_module_dir

并反复这样做。

在“编辑”模式下安装模块

如果你想用最新版本的方式安装这些,你可以使用“编辑”安装模式

$ pip install -e ../other_module_dir

使用这种方法,如果您修改 ../other_module_dir 项目中的代码,下次将在更新版本中导入。

使用requirements.txt自动安装模块

要自动安装,您最终可以将所有依赖项转储到(通常)名为 requirements.txt 的文件中:

$ pip freeze > requiremetns.txt

编辑它(删除,不属于那里的,最后你可以一步安装所有依赖模块:

$ pip install -r requirements.txt

结论

最苛刻的(但不是那么困难)是使用setup.py 使您的模块完整。一旦你做到了这一点(并且这项技能将在以后多次得到回报),你的整个导入场景将变得微不足道,只需遵循你导入的模块的名称并使其可用(我建议使用绝对导入)。

注意:使用virtualenv来做这种工作,不是必须的,但它会让你的工作更简单。

【讨论】:

  • 我应该更清楚地说明这些模块存在于一个包中。对于应该通过 Python 的内置导入管理使用简单的__import__("Project.modules.category.module", fromlist=["Project.modules.category"]) 来实现的事情,这似乎是不必要的复杂
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 2018-11-08
  • 2013-12-28
  • 1970-01-01
  • 2018-12-21
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多