2017-01-04 5 views
0

@gen.coroutineデコレータを使用して、GETリクエスト用の非同期コルーチンを使用しているPython3 tornado Webサーバで作業しています。Pythonジェネレータとreduce

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

十分に単純である:私は図書館から本機能を使用したい

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

は今など、複数の機能foo1foo2は、同じタイプであると仮定します。私はgetの方法でちょうどresponse(foo(x))の代わりに...foo3(foo2(foo1(x).result()).result())...yieldのようなものをしたいと思います。

reduceresultの方法ではこれが簡単だと思いました。しかし、tornadoの仕組みのために、fooresultメソッドで何かを返すよう強制することはできません。つまり、yield reduce(...)は「DummyFutureは結果のブロックをサポートしていません」というエラーを表示します。 SOおよび他の場所で他の回答からは、私は私は私は本当に理解していないIOLoopか何かを、使用する必要があります知っている、と...

...私の質問は、どのように私はすべてのを評価避けるすることができますfooyieldは、getメソッドの評価されていないチャンクですか? 1.巣機能の多くと2がないがすぐに評価しよう:

編集:私はしたいので、これはthis questionの複製ではありません。

+0

の可能性のある重複した[竜巻で先物に()の結果を呼び出すことはできません] (http://stackoverflow.com/questions/31172272/cant-call-result-on-futures-in-tornado) – Natecat

+0

ネスティングをシミュレートする関数(-like)オブジェクトを返すことを意味する場合、[this](http ://stackoverflow.com/questions/15331726/how-does-the-functools-partial-work-in-python)は適切な複製です – Natecat

答えて

1

竜巻では、yield未来にコルーチンを入れて結果を得る必要があります。 Tornado's coroutine guideを確認してください。

コルーチンであるレデューサーを書くことができます。それは、未来を得るために、それぞれのコルーチンを実行し、結果を得るために、将来に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) 
+0

ありがとう、これは理にかなっています。 coreduce関数内で何が起こったのかを複数のyield文とreturn文で説明してください。 – shardulc

+1

各 "yield"は呼び出されたコルーチンが完了するのを待って、未来を解決して結果に返します。 "return"ステートメントはコルーチンから値を返します。コルーチンが返すものは、将来の価値になります。 –

+0

"コルーチンが返すものはどれでも、将来の価値になります。"これはコルーチンに関するこれまでに聞いたことのある最も有用なステートメントです。どうもありがとうございました! – shardulc

関連する問題