2

ラッパー関数内でデコレータの引数にアクセスしようとしていますが、うまくいきません。

私が持っているものは次のとおりです。

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()

デコレータの引数にアクセスできない理由が本当にわかりません。

4

2 に答える 2

3

arg1とにアクセスすることはできますarg2が、「拡張された」代入演算子を使用しても、これらの名前に代入しないでください。内部関数でローカル変数になるためです。表示されるエラー メッセージは、まさにこれを実行しようとしたことを示しています (ただし、コードは示していません)。

Python 3 では、次を使用してこの問題を回避できます。

nonlocal arg1, arg2

のどこかwrapper()

于 2011-02-10T21:36:04.587 に答える
0

arg1とで何をするかによって異なりますarg2。通常、クロージャーは余分な作業をしなくても完全に機能します。ただし、内部関数でそれらを再割り当てすると、Python はそれがローカル変数であると想定し、そうでないことを伝える必要があります。

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

あなたの問題は、にwrapper渡すselfことmethodです。ありませんself。あなたはそれを取らなければならないでしょう(そしてそれでも、デコレータをメソッドに制限します-なぜself滑り込ませないの*argsですか?).

self「グローバル名が定義されていません」から「割り当て前に参照」をどのように読んだかわかりません...

于 2011-02-10T21:36:36.730 に答える