在Flask中,只需将变量分配给`g`一次即可用于应用程序。

6

我想保存一个昂贵函数的结果对象。在任何请求之前,这个昂贵的函数应该只被处理一次。

我查看了Flask的文档,并考虑使用g来保存结果,并使用@app.before_first_request装饰器来确保这个赋值只发生一次。

我的代码如下:

@app.before_first_request
def before_first_request():
    g.rec = take_long_time_to_do()

@app.route('/test/')
def test():
    return render_template('index.html',var_rec=g.rec)

然而,这些代码不够完善。它只在第一次调用“test”请求时起作用。当我第二次访问“myapplication/test”时,g.rec不存在,这将引发异常。
有没有人有关于如何在应用程序初始化时将全局变量赋值给g的想法?
3个回答

5

g是该请求的全局对象。您考虑过使用缓存机制吗?

> pip search flask | grep "cache" | sort
Flask-Cache               - Adds cache support to your Flask application
Flask-Cache-PyLibMC       - PyLibMC cache for Flask-Cache, supports multiple operations
Flask-Memsessions         - A simple extension to drop in memcached session support for Flask.

然后你可以将 take_long_time_to_do() 的结果存储在那里,如果存在则检索它。


谢谢,sberry。在那个应用程序中我可以使用一个全局不可变对象吗?为什么我应该使用catching而不是全局对象? - Hanfei Sun
同意 - Flask-Cache 非常强大,你可以缓存到内存/文件/redis并设置超时等。 - Alex L
查看caching other functions示例。 - Alex L
@Firegun:不,没有一个全局对象可用于所有请求。这就是缓存的作用。 - sberry
1
@sberry 你说的“没有全局对象可用于所有请求”是什么意思?我可以在app = Flask(__name__)之后分配一个全局对象,例如rec=100,然后我可以在任何查看器函数中使用这个变量rec。不是吗? - Hanfei Sun
另一个缓存选项是dogpile.cache - Audrius Kažukauskas

0
你可以尝试将该函数调用放在你项目包的__init__.py中吗?我通常使用__init__.py来初始化app = Flask(__name__)等内容。所以你可以尝试以下操作:
# __init__.py:

from flask import Flask
from somemodule import take_long_time_to_do
app = Flask(__name__)
rec = take_long_time_to_do()

然后,只要您导入它,就可以在任何视图中使用rec变量:

# views.py

from myproject import rec
@app.route('/test/')
def test():
    return render_template('index.html',var_rec=rec)

0

通常情况下,缓存是解决这个问题的方法。但是假设您有一个一次性的值,并且由于某些原因不想引入缓存基础设施(该值不会超时),您也可以在应用程序启动时将其计算为模块全局变量,使用它,并/或在需要时导入它。

如果模板中需要该值:

  • 通过上下文处理器将其添加到模板中。
  • 在应用程序初始化之前将其添加到配置模块中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接