2017-07-04 8 views
2

シンプルで複雑なAPIを使ってクラスを作成しています。このAPIの一部であるすべてのメソッドはコルーチンでなければなりません。コルーチンからPythonのコルーチンを呼び出す

このクラスの外から、私はまだコルーチンのようなメソッドを呼び出したいと思います。私は(それだけの単純な呼び出しのための時間を無駄にするような感じ)イベントループと背中にジャンプを防ぎたいので

x = MyClass() 
loop = asyncio.get_event_loop() 
result = loop.run_until_complete(x.simple1(42)) 

今私はsimple1からawaitsimple2呼び出しを削除したいと思います。

これを行う方法はありますか?もちろん、すべての解決策は、awaitのアプローチのオーバーヘッドを超えてはなりません。

答えて

3

あなただけself.complex()を呼び出すと直接を生成することコルーチンを返すことができます。

class MyClass: 
    async def complex(self, **kwargs): 
     x = compute(kwargs) 
     return await asyncio.sleep(x) 

    def simple1(self, param): 
     return self.complex(a=param, b=None) 

    def simple2(self, param): 
     return self.complex(a=None, b=param) 

これは、発信者に直接complex()コルーチンを渡します。結局のところ、は、遅延実行用のコルーチンオブジェクトを生成します。同じオブジェクトが他の同期呼び出しを介して渡される可能性があります。MyClass().simple1('foo')は、complex()メソッド本体を直接実行する別のコルーチンオブジェクトを作成して、そのオブジェクトに代わってラッパーを生成することはありません。

しかし、asyncawaitキーワードの追加は、方法はコルーチンを作ることをあなたのコードの読者にそれを明確にします。オーバーヘッドは最小限に抑え、保持することを検討してください。

+0

この解決法は、「シンプル*」がコルーチンであり、別のプログラマーが「ブロッキング」コールだと考えることができますが、そうではありません。 – Qeek

+0

@Qeek:** **はブロッキングコールです。 'complex()'の作業が完了するまで戻りません。 –

+0

多分私は何かが間違って待っている。私がcoroutineを呼び出すと、イベントループが何らかの処理を待っている(たとえ、 'await coro()'と呼ばれる直前にパケットが到着した)場合でも、イベントループは常に私のコルーチンを直ちに処理するのでしょうか? – Qeek

関連する問題