问题描述
由tornado.gen 有人可以帮助我了解tornado.gen之间准确的区别.coroutine和tornado.gen.engine
Going by the tornado.gen documentation can someone help me understand the exact difference between tornado.gen.coroutine and tornado.gen.engine
推荐答案
由于龙卷风文档 gen.engine
说:
这装饰类似于协程,但它不返回
未来和回调参数没有经过特殊处理。
和作为 gen.coroutine
文件说
从呼叫者的角度来看,@ gen.coroutine类似于
@return_future和@ gen.engine的组合。
gen.engine
基本上是协同程序做什么的老,少精简版。如果你正在编写新的code,你应该遵循的文件的意见,并总是用 tornado.gen.coroutine
。
gen.engine
is basically an older, less streamlined version of what coroutine does. If you're writing new code, you should follow the documentation's advice and always use tornado.gen.coroutine
.
如果你看一下code这两个功能(与剥离出来的文档)这是pretty明显。
It's pretty evident if you look at the code for both functions (with documentation stripped out).
引擎:
def engine(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
runner = None
def handle_exception(typ, value, tb):
if runner is not None:
return runner.handle_exception(typ, value, tb)
return False
with ExceptionStackContext(handle_exception) as deactivate:
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = getattr(e, 'value', None)
else:
if isinstance(result, types.GeneratorType):
def final_callback(value):
if value is not None:
raise ReturnValueIgnoredError(
"@gen.engine functions cannot return values: "
"%r" % (value,))
assert value is None
deactivate()
runner = Runner(result, final_callback)
runner.run()
return
if result is not None:
raise ReturnValueIgnoredError(
"@gen.engine functions cannot return values: %r" %
(result,))
deactivate()
# no yield, so we're done
return wrapper
协程:
def coroutine(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
runner = None
future = TracebackFuture()
if 'callback' in kwargs:
callback = kwargs.pop('callback')
IOLoop.current().add_future(
future, lambda future: callback(future.result()))
def handle_exception(typ, value, tb):
try:
if runner is not None and runner.handle_exception(typ, value, tb):
return True
except Exception:
typ, value, tb = sys.exc_info()
future.set_exc_info((typ, value, tb))
return True
with ExceptionStackContext(handle_exception) as deactivate:
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = getattr(e, 'value', None)
except Exception:
deactivate()
future.set_exc_info(sys.exc_info())
return future
else:
if isinstance(result, types.GeneratorType):
def final_callback(value):
deactivate()
future.set_result(value)
runner = Runner(result, final_callback)
runner.run()
return future
deactivate()
future.set_result(result)
return future
return wrapper
这两个可能是pretty很难第一眼就明白了。但尽管如此,很明显,在code非常相似,不同的是 @ gen.coroutine
的回调的一些特殊的处理
kwarg,和它建立/返回未来
。 @ gen.engine
有一些code,如果你试图从它返回的东西,而不是把它在未来专门抛出一个错误
。
Both of these are probably pretty hard to understand at first glance. But still, it's obvious that the code is very similar, except that @gen.coroutine
has some special handling of the callback
kwarg, and it builds/returns a Future
. @gen.engine
has some code that specifically throws an error if you try to return something from it, rather than putting it in the Future
.
这篇关于差在tornado.gen.engine V / S tornado.gen.coroutine的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!