在Greenlet中访问flask.g [英] Access flask.g inside greenlet

查看:99
本文介绍了在Greenlet中访问flask.g的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Flask + gevent,并且想访问 flask.g 在greenlet目标函数内部的全局应用程序. 我正在使用 copy_current_request_context 装饰器,情况很漂亮类似于文档中给出的示例:

I'm using Flask + gevent and want to access the flask.g application global inside the target function of a greenlet. I'm using the copy_current_request_context decorator and have a situation pretty similar to example given in the docs:

import gevent
from flask import copy_current_request_context, g

@app.route('/')
def index():
    g.user_data = 'foobar'
    g.more_user_data = 'baz'

    @copy_current_request_context
    def do_some_work():
        some_func(g.user_data, g.more_user_data)
        ...  

    gevent.spawn(do_some_work)
    return 'Regular response'

但是,出现以下错误:

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

我认为复制请求上下文时会推送新的应用程序上下文吗?我在此处的Flask代码中设置了跟踪似乎是这样.因此,错误并不出人意料,因为flask.g对象的应用程序上下文范围为0.10(请参阅

I think a new application context is pushed when the request context is copied? I set a trace in the Flask code here and that seems to be the case. So the error isn't all that surprising because the flask.g object is application context scoped as of 0.10 (see http://flask.pocoo.org/docs/0.12/api/#flask.Flask.app_ctx_globals_class).

很明显,我可以将用户数据作为参数传递给目标函数:

Obviously, I can just pass the user data into the target function as arguments:

import gevent
from flask import g

@app.route('/')
def index():
    g.user_data = 'foobar'
    g.more_user_data = 'baz'

    def do_some_work(user_data, more_user_data):
        some_func(user_data, more_user_data)
        ...  

    gevent.spawn(do_some_work, g.user_data, g.more_user_data)
    return 'Regular response'

这很好用,但是我希望尽可能使用flask.g.

And this works just fine, but I was hoping to use flask.g if possible.

推荐答案

flask.g如文档所述:

flask.g is bound with the app context, not on request context, as the doc says:

从Flask 0.10开始,它存储在应用程序上下文中,而不再存储在请求上下文中...

Starting with Flask 0.10 this is stored on the application context and no longer on the request context ...

copy_current_request_context()仅复制请求上下文,但为您提供新的应用程序上下文.您可以创建一个以关闭的方式传递当前应用上下文:

copy_current_request_context() only copy request context, but give you a new app context. You could create one to pass current app context with closure:

def copy_current_app_context(f):
    from flask.globals import _app_ctx_stack
    appctx = _app_ctx_stack.top
    def _(*args, **kwargs):
        with appctx:
            return f(*args, **kwargs)
    return _

但是,我更喜欢通过更清晰的参数将数据传递给greenlet.

However, I prefer pass data to greenlet explicitly via arguments, which is cleaner.

这篇关于在Greenlet中访问flask.g的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆