2011-02-10 5 views
2

imはラッキー関数内でデコレータ引数にアクセスしようとしています。デコレータラッパー関数内のデコレータ引数にアクセスする

def my_decorator(arg1=False, arg2=None): 

    def decorator(method): 
     @functools.wraps(method) 
     def wrapper(method, *args, **kwargs): 
      # do something based on arg1 and arg2 
      # accessing one of the two named arguments 
      # ends up in a 'referenced before assignment' 

      arg1 = arg1 # error 
      arg2 = arg2 # error 

      newarg1 = arg1 # working 
      newarg2 = arg2 # working 

      return method(*args, **kwargs) 
     return wrapper 
    return decorator 

と私はデコレータの引数にアクセスすることはできませんなぜ私は本当に理解していない通常のデコレータ

@my_decorator(arg1=True, arg2='a sting or whatever else') 
the_function() 

のようにそれを使用します。

私は何を持っていることです。

答えて

2

arg1arg2にアクセスできますが、これらの名前には「拡張」代入演算子を含めて割り当ててはいけません。これにより、内部関数のローカル変数になります。表示されるエラーメッセージは、コードを表示していないのに、これを正確に実行しようとしたことを示しています。

は、Python 3では、あなたはwrapper()のどこかで

nonlocal arg1, arg2 

を使用してこの問題を回避することができます。

+0

はそれを指摘していただきありがとうございます。 – aschmid00

0

arg1arg2の処理内容によって異なります。一般に、クロージャは特別な作業をすることなく完全に動作します。しかし、内部関数でそれらを再割り当てすると、Pythonはそれがローカル変数であるとみなし、そうでなければそれを伝える必要があります。

Python 3では、nonlocal arg1, arg2を宣言します。 Python 2では、あなたは不正行為をしなければなりません:2つをリスト(外側関数のarg1 = [arg1])にラップし、内部関数にarg1[0]を使用します。これがなぜ機能するのか説明したい場合は、このトピックに関するPythonの質問を検索するか、ドキュメントを参照してください(私が信じる言語リファレンスのどこかで検索します)。

wrapperは、selfからmethodになります。 selfはありません。あなたはそれを取らなければならないでしょう(そして、デコレータをメソッドに限定しても、self*argsに入れるのはなぜですか?)。

私はあなたが「グローバル名 selfが定義されていない」から「割り当ての前に参照さ」をお読み方法を確認するために失敗し

...

+0

私はこれらのargsを再割り当てせず、私はpython2xを使用しますが、アクセスできません。彼らは割り当てられていないと私に伝えます。 – aschmid00

+0

@ aschmid00:コードを表示する必要があります。 – delnan

+0

@delnan:表示するコードがあります。 arg1またはarg2は、ラッパー関数内ではアクセスできません。私はそれらを再割り当てする必要はありません、それらが真か偽か、arg2の値は何かを知るだけです – aschmid00

関連する問題