2017-04-11 4 views
0

python3.6でコルーチンオブジェクトの関数と引数を抽出することは可能ですか?コルーチンからの関数と引数の抽出

コンテキスト:現在、私はこのようなものがあります:

async def func(*args): 
    ... 

ret = await remotely(func, x, y) 
ボンネットの下

remotely漬物funcx、およびyを、それはそれらをunpickles別のサーバーに、func(x,y)を実行することをSCPの、ピクルス結果、scpはそれを返し、最後にそれをretに埋め込みません。

このAPIは、私が持っていることを好むだろう、私には不快に感じている:

ret = await remotely(func(x, y)) 

私はfunc(x, y)によって表されるコルーチンオブジェクトをpickle化することができれば、私はこれを行うことができますが、私は私が得ることを試みたとき:

TypeError: can't pickle coroutine objects 

だから私の代わりの望みは、私はそれゆえ、この質問、f(x, y)からfx、およびyを取り出すことができるということです。

答えて

2

したがって、ret = await remotely(func(x, y))を実行すると、funcのコルーチンオブジェクトが実際に構築されます。幸いにも、必要な情報をコルーチンオブジェクトから抽出することができます。このオブジェクトは、リモート実行のために送信することができます。

まず、__qualname__属性を使用して関数名を取得できます。これにより、完全修飾名が与えられます。つまり、コルーチンがネストされている場合は、関数への完全なパスが得られます。

次に、コルーチンのフレームオブジェクトから引数の値を抽出することができます。

これは一つだけ注意点があります

async def remote(cr): 
    # Get the function name 
    fname = cr.__qualname__ 

    # Get the argument values 
    frame = cr.cr_frame 
    args = frame.f_locals # dict object 

    result = await ... # your scp stuff 

    return result 

のようなあなたの remote機能がどのように見えるかです。あなたは、ほとんどである(ハーフウェイが実行さ...つまり、コルーチンは「新鮮」でなければなりませんつまり

ret = await remotely(func(x, y)) 

、機能だけで、あなたが投稿した方法を使用すべきであることを示し、そしてべきではありませんそれをすぐに開始してremoteに渡すと不可能です)。そうでない場合、f_localsの値には、awaitより前に定義されている他のローカル変数も含まれます。

+0

ありがとうございます。私の同僚は実際に私のポストの直後に問題を解決することに成功し、 'dill'ソースをハッキングして、コルーチンオブジェクトを直接pickleすることができました。彼は独自に引数値を取得するのと同じテクニックを思いついたのですが、 '__qualname__'なしで関数を得るための別のテクニックを思いつきました。 – dshin

+0

あなたはそれが解決してうれしい。たぶん別の答えとして作業ソリューションを投稿する必要がありますか? – bagrat

関連する問題