如何在龙卷风中创建多个add_callback



我试图在龙卷风主循环中添加多个回调。但是当我运行这段代码:

def task(num):
    print 'task %s' % num
if __name__ == '__main__':
    for i in range(1,5):
        tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(num=i))
    tornado.ioloop.IOLoop.instance().start()

我得到5次输出:'task 5',而不是task 1..任务5。当我像这样修改main时:

tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(1))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(2))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(3))
tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(4))

一切正常(我在输出中得到task1-task5)。在第一种情况下我做错了什么?

也许有同样的问题,就像在JS?看看这个答案:JavaScript闭包内循环-简单的实际例子

"问题是变量i,在你的每个匿名函数中,都被绑定到函数外的同一个变量。"

try simple test:

def task(num):
    print 'task %s' % num
def create_task(num):
    tornado.ioloop.IOLoop.instance().add_callback(callback=lambda: task(num))
if __name__ == '__main__':
    for i in range(1,5):
        create_task(i)
    tornado.ioloop.IOLoop.instance().start()

将lambda封装到functools.partial()函数中以解决"指针问题" IOLoop.instance().add_callback(callback=functools.partial(task, i*10))

tl;博士;

下面是一个"指针问题"的例子:

def task(num):
    print(num)
for i in range(1, 6):
    print ("poop {0}".format(i))
    IOLoop.instance().add_callback(callback=lambda: task(i))
IOLoop.instance().start()
上面i代码示例中的

将是指向range()当前迭代的值的内存指针。从1到2,再到3、4、5。

Tornado的add_callback()异步函数立即将控制返回给主程序,使得对task()函数的所有5个调用几乎同时执行。此时i已经得到了5的值。

为了快速解决这个问题,使用funtools.partial函数代替lambda,并研究两者的区别;)

下面是一个没有bug的例子:

IOLoop.instance().add_callback(callback=functools.partial(task, i*10))

相关内容

  • 没有找到相关文章

最新更新