Python 自定义装饰器中的Tornado异步操作
我正在尝试使用redis和tornadis库为我的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
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实例的名称!但是你能解释一下订购装饰师的逻辑吗?