2017-09-21 10 views
0

以下は、私がやろうとしている単純な例です。以下の関数 'print_number'は2つのデコレータで囲まれています。上記リターンPythonで複数のデコレータを使って各デコレータから元の関数を実行

222 executed from test_decorator 
None executed from another_decorator 
None 

def another_decorator(function): 
    def wrapper(*arg, **kwargs): 
     ret = function(*arg, **kwargs) 
     print(ret, "executed from another_decorator") 
    return wrapper 

def test_decorator(function): 
    def wrapper(*arg, **kwargs): 
     ret = function(*arg, **kwargs) 
     print(ret, "executed from test_decorator") 
    return wrapper 

@another_decorator 
@test_decorator 
def print_number(num): 
    return num 
x = print_number(222) 
print(x) 

あなたが見ることができるように、唯一のtest_decoratorはラップprint_number機能を実行することができました。この関数の呼び出しはanother_decoratorで完全にスキップされました。 私はこれがなぜ必要なのかに関するいくつかの文脈。私は、デコレータごとに非同期関数を呼び出す必要がある、複数のデコレータを持つメインの非同期関数をラップするコードをいくつか用意しています。各デコレータは、aiohttpセッションが作成され、コルーチンがensure_futureを使用してスケジュールされる、呼び出された非同期関数に渡すいくつかの予備作業を行います。 ラップされた関数 'function'を各デコレータから呼び出す方法や可能な手順はありますか?あなたが実際にあなたのデコレータに返す必要が

答えて

1

.. .additionally機能は、単に「オリジナル」ので、あなたのラッパー関数は、属性を与えるpythonで

def another_decorator(function): 
    def wrapper(*arg, **kwargs): 
     ret = function(*arg, **kwargs) 
     print(ret, "executed from another_decorator") 
     return ret 
    wrapper.original = getattr(function,"original",function) 
    return wrapper 

def test_decorator(function): 
    def wrapper(*arg, **kwargs): 
     ret = function(*arg, **kwargs) 
     print(ret, "executed from test_decorator") 
     return ret 
    wrapper.original = getattr(function,"original",function) 
    return wrapper 
+0

おかげオブジェクトされています。これは本当に興味深いことですが、ここで何が起こっているのかがわかりにくいですが、これはうまくいきます。 getattrでは、 'original'はオブジェクト 'function'に存在しないので、デフォルトの 'function'値を取得しています。私は躊躇して、値 '実行'関数の検索と 'print_number'関数が呼び出されることを認めています。しかし、私は本当になぜこれが機能するのか分かりません。以前はfunctool.wrapsを使用していましたが、function__。wrapped __()を 'another_decorator'で実行しようとしましたが、うまくいきませんでした。 – user2993021

関連する問題