【问题标题】:Is it possible to import variables from __init__.py in views.py?是否可以在views.py 中从__init__.py 导入变量?
【发布时间】:2017-05-17 16:57:17
【问题描述】:

我有一个烧瓶应用程序,我在其中对一些数据进行了一些分析,并根据这些数据绘制了一些图表。然而,到目前为止,我一直在我的 views.py 文件中的 index 方法中执行图形的分析和绘制。这不是很好,因为每次我在浏览器中执行“刷新”时,它都会重做整个分析并重新绘制图表。

我的项目结构如下:

Data Analysis/
  - app/
    - static/
    - templates/
      - base.html
      - index.html 
    - __init__.py
    - models.py
    - views.py
  - venv/
  - run.py
  - config.py

我想将我的数据分析移至我的 __init__.py 模块,因为这将导致仅在应用程序运行后计算所需的数据,而不是在每次刷新时重新运行它。我遇到的障碍实际上是从我的 __init__.py 模块中导入我需要的数据到我的 views.py 模块中。

这是怎么做到的?

我尝试了以下方法:

__init__.py

from flask import Flask, url_for, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

def do_data_analysis():
    #... lots of calculations

    return data

VALUES = do_data_analysis()

views.py

from app import app, models, __init__ #does not work
from __init__ import VALUES #does not work
import VALUES #does not work
from app import VALUES # does not work
VALUES = __init__.VALUES #does not work

是否有另一种可能更合适的方法来做到这一点?

编辑:

我已经设法通过创建一个模块 (data_analysis.py) 使其工作,我在其中执行所有数据分析。这也意味着在我的__init__.py 中我删除了我的数据分析,而我现在在我的view.py 中有以下内容:

from app import data_analysis

现在我可以做:

GPSVALUES = data_analysis.VALUES
#do something with the values..

然而,它似乎确实运行了两次脚本。首先在我的run.py 启动时。然后在第一个请求进来时再次。它似乎只在启动run.py 时运行脚本。如果页面被刷新,它不会重新运行我最初想要的脚本。因此,除非没有其他解决方案,否则我认为我会采用此解决方案。(我会在完成更多测试后立即添加答案)

【问题讨论】:

  • 你的前提是有缺陷的。在__init__ 中没有代码,这意味着它只会运行一次;您可以通过将其放在 views.py 中的模块级别来获得相同的效果。
  • 如果我要在与我的views.py 相同的文件夹级别中为我的数据分析创建一个辅助模块,我需要在某个地方运行它。如果我要在我的views.py 中运行它,它并不能真正解决我的问题。
  • 是的,如果您在模块级别运行它。
  • 你将不得不解释这意味着什么......或者至少指出我可以找到解决方案的地方

标签: python flask import module python-3.5


【解决方案1】:

试试

import __init__
VALUES = __init__.VALUES

from app import app, models, __init__ 

失败,因为如果 app 不在您的范围内,则无法从它导入。

from __init__ import VALUES

失败,因为 VAULES 是一个变量,而不是一个模块/函数。

import VALUES

失败是因为,嗯...没有VALUES 模块。

【讨论】:

  • 遗憾的是不起作用。我得到ImportError: No module named '__init__'
  • 没想到import __init__ 会起作用,但它确实起作用了!
【解决方案2】:

试试,

from app import VALUES

这可能有效。

如果您只想在应用程序中进行一次数据分析,请阅读这些烧瓶装饰器,

【讨论】:

  • from app import VALUES 似乎也不起作用。我将如何使用这两个装饰器,我已经进行了一些搜索,但实际上找不到任何示例。
  • import 会出现什么错误?.. 对于那些装饰器,请在函数声明上方添加 @app.before_first_request。添加它会在处理到达应用程序的第一个请求之前调用该函数一次。请注意,这样装饰的函数不能返回任何内容。
  • ImportError: cannot import name 'GPSVALUES'(我已将其重命名为使用多种类型的值)。
【解决方案3】:

毫无疑问,这个答案来得太晚了。

看起来也找到了答案,但其原因有点模糊,留下一些空间来说明__init__.py 如何帮助组织扩展项目,例如,通过允许目录中的模块离散类别函数(到模块中),然后可以通过一个名称(模块所在文件夹的名称)引用,只记住该文件夹中收集的一堆文件中的函数名称,并以该名称正确导入它们.

在__init__.py 中添加几行将配置它以公开文件夹中包含的模块,它自然会变成一个包,即在本例中为文件夹“app”。

到文件夹'app'中的__init__.py,尝试添加:

from .models import <name of defs to expose>
from .views import <name of defs to expose>

然后,在 views.py 中,导入应该进入的模块,将 from app import app, models, __init__ 替换为:

app import app
from app import app <list of exposed fns needed here>

不要尝试在任何地方导入__init__.py,而是在应用程序中创建一个模块,其中包含您希望通过__init__.py 向应用程序的其余部分公开的功能,仅使用对“应用程序”的引用。

基本上,这里发生的所有事情都是使模块名称透明化,并且将它们公开的功能分组在文件夹名称下。 __init__.py 通过将它所在的文件夹变成一个包来实现这一点。该包可以放在 PYTHONPATH 上,或者在 import 语句中对它的引用可以以路径名 -relative 或 -absolute 方式完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2020-03-02
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 2017-03-12
    • 2015-07-30
    相关资源
    最近更新 更多