我有一些使用tornado gen.coroutine 的异步函数,这些函数通常用作基于 Tornado 的Web应用程序的一部分。但是,我想从一个普通的旧python脚本中调用其中一些命令来执行一些管理任务。我该怎么做呢?

from tornado import gen

import some_internal_stuff

@gen.coroutine
def myfunc(x):
    y = yield some_internal_stuff.another_async_func(x)
    raise gen.Return(y)

if __name__ == "__main__":
    # What do I put here to call myfunc(1) and get the async return value?
    pass

更新:

一个更具体的例子:
from tornado import gen

@gen.coroutine
def another_async_func(x):
    print "aaf"
    raise gen.Return(x + 1)

@gen.coroutine
def myfunc(x):
    print "myfunc"
    y = yield another_async_func(x)
    print "back"
    raise gen.Return(y)

def callback(y):
    print "Callback called with %d" % y

if __name__ == "__main__":
    myfunc(1, callback=callback)

运行此输出:
myfunc
aaf

最佳答案

run_sync中有一个内置方法IOLoop可以运行一个调用然后停止循环,因此,只要在PYTHONPATH中有 Tornado ,只需将事件循环添加到一个简单的python脚本中就很简单了。

举一个具体的例子:

from tornado import gen, ioloop

@gen.coroutine
def another_async_func(x):
    print "aaf"
    raise gen.Return(x + 1)

@gen.coroutine
def myfunc(x):
    print "myfunc"
    y = yield another_async_func(x)
    print "back"
    raise gen.Return(y)

@gen.coroutine
def main():
    y = yield myfunc(1)
    print "Callback called with %d" % y

if __name__ == "__main__":
    ioloop.IOLoop.instance().run_sync(main)

输出:
myfunc
aaf
back
Callback called with 2

注意run_sync嵌套不好;如果您在同一run_sync上的run_sync调用的函数中调用IOLoop,则内部调用的完成将停止IOLoop,并且内部调用之后将不再返回yield

10-05 22:42
查看更多