2016-09-08 3 views
0

私は複数の構成でライブラリを持つアプリケーションている:現在、私はコードのことを非同期、トルネードコルーチン、または標準の関数呼び出しを一般化する方法は?

  • Python2.7ネイティブ
  • Python2.7竜巻
  • Python3.5

asyncioを持っています3つすべてに対してほぼ同じですが、各関数呼び出しの呼び出し方法には若干の違いがあります。これは私が多くの場所で、次のようなものを持っているので、私は、コードの重複のトンを持っていることを意味:

clientはそれぞれネイティブのpython、asyncio、と竜巻をサポートする、言語固有の実装です
#Python2.7native.py 
def main(client): 
    client.foo(args) 
    client.bar(args) 

#Python2.7tornado.py 
@gen.coroutine 
def main(client): 
    yield client.foo(args) 
    yield client.bar(args) 

#Python3.5asyncio.py 
async def main(client): 
    await client.foo(args) 
    await client.bar(args) 

。 APIメソッド呼び出しは同じです。私は何とか私は、適切に、私は別のファイルにメソッドを定義して使用する方法について考えてきました

さまざまなメソッドを呼び出し、共有ファイルに含めることができる単一のメソッドにこれを一般化することができるように期待しています

getattrテストを正しく呼び出すことができますが、これは本当に面倒です。

これを行うには良い方法がありますか?

+0

実際には、どのようにcalleであるかを除いて、さまざまなセクションで同じですd、関数のリストを作成し、プラットフォーム固有のランナーがそのリストを反復してそれに応じて呼び出すことができますか? –

+0

問題は ''非同期def''です。私の知る限りでは、2.7の同等物はありません。 Pythonの複数のバージョン間で共有する必要がある場合は、それらの関数の '' gen.coroutine''を選択します。 –

答えて

-1

使用@gen.coroutineおよびyield:これはすべてのPythonバージョンで機能します。 gen.coroutineで装飾された関数は、ネイティブのコルーチンから少し遅くなっていますが、すべての同じシナリオで使用できます。同期の場合については

run_syncを使用します。

result = IOLoop.current().run_sync(main) 
+0

これはどのように私の質問に答えますか?私は、asyncio、竜巻、および通常のpythonの実装をサポートする必要があります。 – enderland

1

あなたは1つの関数にこのすべてを行うことはできません - どのようにclient.foo()は、それが「正常な」同期アプリケーションから呼び出されたのかどうかを知ることになっている、またはその呼び出し元がyieldまたはawaitを使用するかどうか。ただし、Tornadoを依存関係として使用したい場合は、すべてのコードを3回複製する必要はありません。他に

@gen.coroutine 
def foo(args): 
    yield something() 
    yield something_else() 
    raise gen.Return(another_thing()) 

client_sync.py、このようなスレッドローカルIOLoopためIOLoop.run_sync()client_async.pyから各機能をラップ:

つのモジュール、client_async.pyでは、トルネードの@gen.coroutineを使用して、機能(複数可)を実装します。

import client_async 
import threading 
import tornado.ioloop 

class _LocalIOLoop(threading.local): 
    def __init__(self): 
     self.value = tornado.ioloop.IOLoop() 
local_ioloop = _LocalIOLoop() 

def foo(args): 
    return local_ioloop.value.run_sync(lambda: foo_async.my_func(args)) 

このコードは、3つの環境のすべてから使用できます。

: - :

import client_sync 

def main(): 
    x = client_sync.foo(args) 

トルネード@gen.coroutineから:async defasyncioから

import client_async 

@gen.coroutine 
def main(): 
    x = yield client_async.foo(args) 

asyncioなしトルネードとasync defを使用することが可能である二つは同義ではないことに注意してください)通常の同期コードから

# one-time initialization for Tornado/asyncio integration 
import tornado.platform.asyncio 
tornado.platform.asyncio.AsyncIOMainLoop().install() 

import client_async 

async def main(): 
    x = await client_async.foo(args) 
関連する問題