如何在烧瓶上存储我自己的变量

时间:2014-03-28 14:20:49

标签: python flask

我需要定义自己的变量,这些变量会在运行时保存在服务器上。我正在尝试使用flask.g,但它会抛出错误:

AttributeError: '_AppCtxGlobals' object has no attribute 'x'

以下是代码:

from flask import *
app=Flask(__name__)
@app.route('/')
def opa():
    #Added this to define variable
    try:
        g.x
    except NameError:
        g.x=None
    #Added this to add value to variable
    if g.x is None:
        g.x='Already defined'
        return 'x is now defined'
    else:
        return g.x
if __name__ == "__main__":
    app.run(host='0.0.0.0',port=8081,debug=True)

2 个答案:

答案 0 :(得分:3)

访问属性会引发AttributeError,而不是NameError

try:
    g.x
except AttributeError:
    g.x = None

最好在这里使用membership testing with in

if 'x' not in g:
    g.x = 'Already defined'
    return 'x is now defined'
else:
    return g.x

我将您链接到的文档也提供了使用g.get()getattr()作为替代方案:

x = g.get('x', None)
# x = getattr(g, 'x', None)
if x is None:
    g.x = 'Already defined'
    return 'x is now defined'
else:
    return x

请注意,g全局上下文仍然与请求相关联;你不能存储从请求到请求持续存在的全局变量。 g支持在应用的不同功能和模板之间共享数据,而不是在请求之间共享数据。

使用实际全局变量(最好通过app.before_first_request() hook设置,或使用某种形式的缓存(例如Flask-Cache)。

设置应用程序范围的全局:

x = None

@app.before_first_request
def set_x():
    global x
    x = 'x is now defined'

通过使用before_first_request,您确保在应用程序启动时只设置x一次,即使您使用的服务器使用多个进程来处理请求。

或者使用缓存:

from flask.ext.cache import Cache

cache = Cache(app)

@cache.memoize(timeout=3600)  # cache for one hour
def produce_x():
    return 'x is now defined'

然后在需要produce_x()时使用x;这在计算x很昂贵时很有用,但必须不时重新计算。

答案 1 :(得分:0)

更简单的方法是按照以下方式执行:

x = getattr(flask.g, 'x', None)
if x is None:
    g.x = 'Already defined'
    return 'x is now defined'
else:
    return g.x

或者,您可以看到代码正在抛出AttributeError。因此,如果您想保留try / catch代码,那么您需要专门捕获AttributeError而不是TypeError

try:
    g.x
except AttributeError:
    g.x=None

if g.x is None:
    g.x='Already defined'
    return 'x is now defined'
else:
    return g.x