Python web应用中的全局变量(Flask)

0 投票
2 回答
5142 浏览
提问于 2025-04-18 18:16

我正在运行一个Python的网页应用,跟我的问题有关。当我从命令行运行它时,一切都正常。它会调用程序的部分,加载一个xml文件,然后从/search/term路径发出的请求,我的网页应用都会返回正确的值。不过,如果我通过Apache来运行它,部分自然就不会执行了。那么,在这种情况下,我该如何一次性打开这个文件,然后在每个请求中都能对它进行查询呢?这可能吗?还是说我应该把数据放到数据库里,这样才能保持数据的持久性?理想情况下,我希望能避免复杂的数据库操作,因为我只是进行简单的字符串搜索。谢谢大家(代码在下面)

Marinero

from flask import Flask
from classes import History
from xmlReader import xmlReader

app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

@app.route('/search/<term>')
def user(term):
    (resultCoords, resultTerms) = historyObj.searchForTerm(term)
    result = "<p>"
    for t in resultTerms:
        result = result + t.string + '<br>' 
    result = result + '</p>'
    return result

if __name__ == '__main__':
    reader = xmlReader("web_history.xml")
    global historyList
    historyList = reader.getData()
    global historyObj
    historyObj = History(historyList)
    app.run()

2 个回答

0

问题在于,当你在 Apache 的 reqest 环境中时,存储在 app context 中的变量是无法使用的。

这里有一段来自 Miguel Grinberg 的优秀书籍中的代码示例,讲述如何在 request 环境中让变量变得全局可用:

@main.app_context_processor
def inject_permissions():
    return dict(Permission=Permission)

所以在你的情况下,可以使用类似这样的代码:

@app.app_context_context_processor
def inject_permissions():
    #return globals here 

这样你就可以在请求环境中访问那些在应用环境中可用的文件了。

编辑:想评论但没有足够的积分。

对 Flask 更有经验的人可能更能回答我们解决方案之间的区别,但我也试着说说。

我实现的代码和你的代码之间唯一明显的区别是,我的代码会自动运行,无论 Flask 应用的环境是什么。这在 app_context 中显然是不必要的。

当应用变得更复杂(比如使用蓝图、不同的配置)时,可能还会出现其他问题,因为这些变量是在其他任何东西之前就被定义了,所以我想修改全局变量会很困难。

编辑 2:对第二条评论的回应:我又看了一遍书,是的,这就是他使用这种模式的原因:

为了避免在每次调用 render_template() 时都要添加模板参数,可以使用上下文处理器。上下文处理器使变量对所有模板全局可用。

0

我来回答我自己的问题。@FoxRocks,我应该选择你的方法而不是我的方法吗?有什么理由吗?非常感谢。对我有效的解决方案是:

from flask import Flask
from classes import History
from xmlReader import xmlReader
from flask.ext.script import Manager

app = Flask(__name__)
manager = Manager(app)
globalString = "hello"
reader = xmlReader("web_history.xml")
global historyList
historyList = reader.getData()
global historyObj
historyObj = History(historyList)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

@app.route('/search/<term>')
def user(term):
    (resultCoords, resultTerms) = historyObj.searchForTerm(term)
    result = "<p>"
    for t in resultTerms:
        result = result + t.string + '<br>' 
    result = result + '</p>'
    return result

if __name__ == '__main__':
    manager.run()

撰写回答