在常规python脚本中使用tornado异步代码

在常规python脚本中使用tornado异步代码,python,asynchronous,tornado,coroutine,Python,Asynchronous,Tornado,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 _

我有一些异步函数,它们通常作为基于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)
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
myfunc
aaf
back
Callback called with 2

IOLoop
中有一个内置的方法
run\u sync
来运行一个调用,然后停止循环,因此只要在PYTHONPATH中有tornado,就可以在普通python脚本中添加一个事件循环

举一个具体的例子:

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)
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
myfunc
aaf
back
Callback called with 2

请注意,
run\u sync
嵌套不好;如果在由
run\u sync
在同一
IOLoop
上调用的函数中调用
run\u sync
,则内部调用的完成将停止
IOLoop
,并且在内部调用返回后不再产生
yield
,这取决于问题的复杂性和您的需求:

if __name__ == "__main__":
    import threading, time
    # The tornado IO loop doesn't need to be started in the main thread
    # so let's start it in another thread:
    t = threading.Thread(target=IOLoop.instance().start)
    t.daemon = True
    t.start()

    myfunc(1, callback=callback)
    # now the main loop needs wait; you can do that by polling a value, sleeping,
    # or waiting on a lock. I've chosen to sleep here, but a lock is probably more
    # appropriate; and, once computation is done, release the lock.
    time.sleep(2)

很抱歉问了这么一个明显的问题,但是是什么阻止了您调用一些\u internal\u东西。直接调用另一个\u async\u func(x)并等待结果?您正在调用的函数是否依赖于Tornado以防止出现这种情况?@rod:其想法是
另一个\u async\u func
是另一个Tornado
@asynchronous
方法,通常在Tornado
IOLoop
存在的情况下运行。我可以运行
另一个\u async\u func
并向它传递一个
回调
,但如果没有tornado运行,
myfunc
中的收益后的行永远不会运行,我传递的回调也不会被调用。