Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 自定义装饰器中的Tornado异步操作_Python_Tornado_Decorator_Coroutine - Fatal编程技术网

Python 自定义装饰器中的Tornado异步操作

Python 自定义装饰器中的Tornado异步操作,python,tornado,decorator,coroutine,Python,Tornado,Decorator,Coroutine,我正在尝试使用redis和tornadis库为我的Tornado路由处理程序构建一个缓存装饰器。 这就是我到目前为止所做的: def rediscache(route): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): result = yield redis.call("GET", "latest_info") print(re

我正在尝试使用redis和tornadis库为我的Tornado路由处理程序构建一个缓存装饰器。 这就是我到目前为止所做的:

def rediscache(route):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            result = yield redis.call("GET", "latest_info")
            print(result)
            func(*args, **kwargs)
        return wrapper
    return decorator
在我的路径处理程序中,我是这样使用它的:

class MainHandler(tornado.web.RequestHandler):

    def initialize(self, db, redis):
        self.db = db
        self.quakes = self.db.quakes
        self.redis = redis

    @gen.coroutine
    @rediscache('route_is_here')
    def get(self):
        ''' ... handler logic here ... '''
问题是,如果我使用我的decorator,我将不再看到处理程序向web输出的内容。如果不是

result = yield redis.call("GET", "latest_info")
我知道

result = redis.call("GET", "latest_info")

然后我又开始在浏览器中看到输出,但这是正确的方法吗?这仍然是异步的吗?如果不是,支撑方法是什么?谢谢

如果您想
产生
协同程序,装饰器中的包装器应该是
gen.coroutine

def rediscache(route):
    def decorator(func):
        @tornado.gen.coroutine
        @wraps(func)
        def wrapper(*args, **kwargs):
            result = yield redis.call("GET", "latest_info")
            print(result)
            if not result:
                new = yield func(*args, **kwargs)
                # save to
        return wrapper
    return decorator
您还需要将装饰程序的顺序更改为:

@rediscache('route_is_here')
@gen.coroutine
def get(self):
    ''' ... handler logic here ... '''
编辑

《装饰师令》解释

@second
@first
def my_func():
    pass

my_func = second(first(my_func))
因此,如果您想在decorator中等待(让渡)您的原始
get
,您必须通过coroutine,因此它必须在
rediscache
之前


更多关于decorators的信息-

redis
库不是异步的<但是,code>tornadis是异步的。我没有看到您在代码中的任何地方使用
tornadis
api。对此我深表歉意。“redis”实际上是tornadis.ClientThis实例的名称!但是你能解释一下订购装饰师的逻辑吗?