2017-07-27 12 views
0

私はクラスメソッドで使用するデコレータを持っています。しかし、私は同じデコレータを使用したいですが、代わりにラッパーとして使用します。デコレータをラッパーとして使用する

例えば、これは私がデコレータを使用する方法である:

myDecorators.py

def authenticate(method): 
    def authenticate_and_call(service_instance, *args, **kwargs): 
     print("Authentification success") 
     #access to service_instance is needed in the decorator 
     print(service_instance.config) 
     return method(service_instance, *args, **kwargs) 

    return authenticate_and_call 

myClass.py

from myDecorators import authenticate 

class MyService: 
    def __init__(self, config): 
     self.config = config 

    @authenticate #I dont want to use a decorator here 
    def execute(self): 
     print(self.config) 
     print("MyService is executed with authentication") 

私がやりたい何か何かでありますlike:

service_callers.py

from myClass import MyService 
from myDecorators import authenticate 

#use the decorator as a wrapper 
def execute_service_with_authentification(): 
    service = MyService({"foo":"bar"}) 
    authenticate(service.execute)(service) 

execute_service_with_authentification() 

これは、次のエラーが返されます。

File "c:\temp\test\myDecorators.py", line 4, in authenticate_and_call 
    return method(service_instance, *args, **kwargs) 
TypeError: execute() takes exactly 1 argument (2 given) 

答えて

2

まず、あなたのMyService.execute definitonから@authenticateデコレータを削除します。次に、authenticateデコレータを使用する必要がある場合は、電話をauthenticate(service.execute)()としてラップしてください。

def authenticate(method): 
    def authenticate_and_call(*args, **kwargs): 
     print("Attempting authentication on object: {}".format(method.__self__)) 
     return method(*args, **kwargs) 
    return authenticate_and_call 
+0

@BelowtheRadar - ちょうど同じ引数を渡す、あなたのラッパーから 'service_instance'を削除/あなたが与えるkwargsから:あなたは自己として最初の引数を渡していない -

あなたが同様にあなたのデコレータを変更してくださいラッパー関数に渡します。 – zwer

+1

@BelowtheRadar - 上記の変更されたデコレータを追加しました。インスタンスメソッドを渡すので、最初の引数は必要ありません。上記はあなたの構造と一緒に動作し、渡す必要のある引数についても動作します(私の元の回答にあるように '裸の呼び出し'に気付くと、私は最初にデコレータを見ていませんでした) – zwer

+1

@BelowtheRadar - あなたはドンそれにアクセスする必要はありません。あなたが渡しているメソッドはすでに 'service'インスタンスにバインドされています。しかし、実際にメソッドを呼び出す前に何かを行う必要がある場合、バインドされたメソッドから 'method .__ self__'を '抽出'できます。上記のアップデートを確認してください。 – zwer