2017-12-04 25 views
6

私はPythonデコレータを使うことを学んでいます。Python:デコレータを使用して関数の内部動作を変更する

def my_dcrtr(fun): 
    def new_fun(): 
     return fun() 
    return new_fun 

デコレータの内部に装飾された機能「fun」がブラックボックスのように機能することがわかりました。 new_funの中でfun()を使用するかどうかを選択することができます。しかし、私は 'fun'に侵入し、new_fun内のfunのローカルスコープと対話できるかどうかはわかりません。

私はPythonでおもちゃのリモートプロシージャコール(RPC)を作ろうとしています。

def return_locals_rpc_decorator(fun): 
    def decorated_fun(*args, **kw): 
     local_args = fun(*args, **kw) 
     # pickle the local_args and send it to server 
     # server unpickle and doing the RPC 
     # fetch back server results and unpickle to results 
     return rpc_results 

    return decorated_fun 


@return_locals_rpc_decorator 
def rpc_fun(a, b, c=3): 
    return locals() # This looks weird. how can I make this part of the decorator? 


print(rpc_fun(2, 1, 6)) 

この例では、実行時に 'locals()'コマンドを使用してrpc_funの引数リストを取得しようとしています。その後、サーバーに送信して実行します。 rpc_funがlocals()を返すのではなく、デコレータを使用して装飾された関数の引数空間を取り出すことは可能ですか?

答えて

3

あなたはのpython3のための機能注釈を使用することができます。

def return_locals_rpc_decorator(fun): 
    def decorated_fun(*args, **kw): 
     local_args = fun(*args, **kw) 
     print(local_args) 
     fun_parameters = fun.__annotations__ 
     final_parameters = {a:list(args)[int(b[-1])-1] for a, b in fun_parameters.items() if a != 'return'} 
     return final_parameters 
    return decorated_fun 

@return_locals_rpc_decorator 
def my_funct(a:"val1", b:"val2", c:"val3") -> int: 
    return a + b + c 

print(my_funct(10, 20, 30)) 

出力:このように

60 
{'a': 10, 'b': 20, 'c': 30} 

は、あなたが飾られ、関数のパラメータとによって指定された詳細な情報にアクセスするためのラッパー関数 decorated_funを使用しています注釈。注釈のパラメータの説明を変更して、各文字列の値が数字の末尾にあるようにして、 argsを索引付けすることができました。ただし、アノテーションのパラメータの説明を変更したくない場合は、終了文字でソートできます。

編集:ラッパー関数(decorated_fun)に呼び出されたときdecorated_funの範囲内で宣言argsは、に渡され、local_argsで解凍されるのでmy_functの本体内のコードが実行されます。

+0

私はこの仕組みを理解できません。私が必要とするのは、 'decorated_fun'内の 'fun_parameters'を実行時に{'a':10、 'b':20、 'c':30}にしてサーバーに送ることができるようにすることです。これは可能ですか? –

+0

@ShichuZhu最近の私の編集をご覧ください。 – Ajax1234

+0

驚くばかり!これは私の問題を完璧に解決する!あなたが気にしない場合、残りの2つの質問:1.機能の本体(つまり、a + b + c)のすべてが決して実行されません。 2.(nvm ...私は間違いをした...) –

関連する問題