1

私はpython 3.4.3でトルネードとモーターに取り組んでいます。

3つのファイルを取得しました。main.pymodel.py、 のように名前を付けましょうcore.py

私には3つの機能があり、それぞれに1つずつ...

main.py

def getLoggedIn(request_handler):
    # request_handler = tornado.web.RequestHandler()
    db = request_handler.settings["db"]
    uid = request_handler.get_secure_cookie("uid")
    result = model.Session.get(db, uid=uid)
    return result.get("_id", None) if result else None

model.py

@classmethod
    def get(cls, db, user_id=None, **kwargs):
        session = core.Session(db)
        return session.get(user_id, **kwargs)

core.py

@gen.coroutine
    def get(self, user_id, **kwargs):
        params = kwargs
        if user_id:
            params.update({"_id": ObjectId(user_id)}) #This does not exist in DB
        future = self.collection.find_one(params)
        print(future) #prints <tornado.concurrent.Future object at 0x04152A90>
        result = yield future
        print(result) #prints None
        return result

呼び出しは次のようになりますgetLoggedIn => model.get => core.get

core.get で装飾されており 、印刷@gen.coroutineを呼び出しますが、結果を返し、関数で戻り値を印刷しようとすると、印刷されます。yield self.collection.find_one(params)print(result)NonegetLoggedIn

これはトルネードの非同期性に関連していると思います.printはyieldの前に呼び出されますが、よくわかりません. 誰かがコルーチン/ジェネレーターの原則と、考えられるさまざまなケースでの動作について説明できれば、非常に役立ちます。

4

2 に答える 2

1

PEP 255は、ジェネレーターの元の仕様をカバーしています。ただし、非常に具体的な方法でコルーチン内でtornado使用します: http://www.tornadoweb.org/en/stable/guide/coroutines.html#how-it-worksyield

tornadoPython のジェネレーターの概念がコルーチンを定義するために採用されているため、コードは実際には通常のジェネレーターのようには見えません。ジェネレーター作成の原則が本当に必要なわけではなく、トルネード ジェネレーターの原則 (まったく別の獣) が必要だと思います。

の値を割り当てることyieldは、ラッピング@gen.coroutineデコレータが Future の結果を に戻す方法core.getです。そうresultすれば、未来のオブジェクトは割り当てられませんが、future.result().

yield future基本的に、関数を一時停止し、futureが呼び出すコールバックに変換して、 の場所で実行を再開しyieldます。の非同期性により、心配していたように、を の前に実行するtornadoことはできません。yieldprint

ほとんどの場合、あなたの Future は何も返さないか、返されますNone(意味的には同等です)。result = yield futureの特殊版と考えたほうがいいかもしれません。result = future.result()

于 2015-09-02T15:47:14.767 に答える
0

コルーチンへのすべての呼び出しは降伏する必要があり、呼び出し元もコルーチンでなければなりません。したがって、getLoggedIn は以下を呼び出すコルーチンでなければなりません。

result = yield model.Session.get(db, uid=uid)

等々。詳細な例と説明については、Tornado コルーチンのリファクタリングに関する私の記事を参照してください。

于 2015-09-02T22:08:45.873 に答える