Python生成器并减少

时间:2017-01-04 02:50:30

标签: python python-3.x generator tornado

我正在使用tornado装饰器处理带有GET请求的异步协同程序的Python3 @gen.coroutine Web服务器。我想从库中使用这个函数:

@gen.coroutine
def foo(x):
    yield do_something(x)

这很简单:

@gen.coroutine
def get(self):
    x = self.some_parameter
    yield response(foo(x))

现在假设有多个相同类型的函数foo1foo2等。我希望在...foo3(foo2(foo1(x).result()).result())...方法中执行类似yieldresponse(foo(x))的操作,而不仅仅是get

我认为使用reduceresult方法会很容易。但是,由于tornado的工作原理,我无法强制foo使用result方法返回某些内容。这意味着yield reduce(...)会出错:“DummyFuture不支持阻止结果”。从SO和其他地方的其他答案中,我知道我将不得不使用IOLoop或其他我不太了解的东西,并且......

...我的问题是,我怎样才能避免评估来自{{foo yield get var gridArray: [[UIView]] = [] for y in 0 ... 10 { var rowArray: [UIView] = [] for x in 0 ... 10 { let cell : UIView! cell = UIView(frame: CGRect(x:10, y:10, width:10, height:10)) self.view?.addSubview(cell) rowArray.append(cell) } gridArray.append(rowArray) } 未评估的大块1}}方法?

编辑:这不是this question的重复,因为我想:1。嵌套很多功能,然后2.尝试立即评估

1 个答案:

答案 0 :(得分:1)

在龙卷风中,你必须在协程中yield一个未来才能获得结果。查看Tornado's coroutine guide

你可以写一个协程的reducer。它运行每个协同程序以获取Future,使用Future调用yield来获得结果,然后在该结果上运行下一个协同程序:

from tornado.ioloop import IOLoop
from tornado import gen


@gen.coroutine
def f(x):
    # Just to prove we're really a coroutine.
    yield gen.sleep(1)
    return x * 2


@gen.coroutine
def g(x):
    return x + 1


@gen.coroutine
def h():
    return 10


@gen.coroutine
def coreduce(*funcs):
    # Start by calling last function in list.
    result = yield funcs[-1]()

    # Call remaining functions.
    for func in reversed(funcs[:-1]):
        result = yield func(result)

    return result


# Wrap in lambda to satisfy your requirement, to 
# NOT evaluate immediately.
latent_result = lambda: coreduce(f, g, h)
final_result = IOLoop.current().run_sync(latent_result)
print(final_result)