【问题标题】:global variables in a python web app (flask)python web应用程序中的全局变量(烧瓶)
【发布时间】:2014-08-23 08:50:55
【问题描述】:

我正在运行我的问题之后的 python 网络应用程序。当我从命令行运行它时,一切正常。它调用程序的 ma​​in 部分加载 xml 文件,随后从 /search/term 路径发出的任何请求我的 Web 应用程序都会返回正确的值。但是,如果我从 apache 运行它,自然不会执行 main。在这种情况下,我如何打开文件一次,然后能够对每个请求进行查询?这是否可能,或者我应该将数据加载到数据库以获得这种持久性?理想情况下,我想避免数据库调用的复杂性,因为我正在执行简单的字符串搜索操作。 提前致谢(代码如下)

水手

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()

【问题讨论】:

  • 新手问题:为什么不能从 if __name__ 块中删除所有其他语句,而 if 块中只有 app.run()

标签: python web-applications flask


【解决方案1】:

回答我自己的问题。 @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()

【讨论】:

    【解决方案2】:

    问题当然是当在 Apache 的reqest 上下文中时,存储在app context 中的变量将不可用。

    这是 Miguel Grinberg 的优秀著作中的代码 sn-p,该书介绍了使变量在 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() 调用中添加模板参数,可以使用上下文 > 处理器。上下文处理器使变量对所有模板全局可用。

    【讨论】:

    • 感谢您回复 FoxRocks。在看到你回复之前,我只是设法让它工作。我的解决方案在哪些方面比你的更糟糕?我的似乎更简单,但我又是个菜鸟。
    • -> 我的应用程序现在有点慢(在 apache 上)。您认为我的解决方案会在每次发出请求时打开文件吗?这违背了目的,可能会使您的解决方案更好。你怎么看?
    • 感谢@FoxRocks 的宝贵时间和明确的回答:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    相关资源
    最近更新 更多