0

私は賢く、セッション変数を呼び出すラッパーを作成し(多くが存在します)、それをセッション変数を必要とする(django)ビューに追加すると思いました。しかし、私は変数のスコープを理解していないか、これを間違って書いているようです。

私が持っているラッパーは次のとおりです。

def s_vars(func_to_decorate):
    @wraps(func_to_decorate)
    def wrapper(request, *args, **kwargs):
        #add all the session variables to kwargs and accessible for the decorated function.
        user_obj = request.user
        datepicker = request.session['datepicker']
        date_format = request.session['date_format']
        .........
        country = request.session['country']
        metric = request.session['metric']
        qrydtm = request.session.get("qrydtm",date.today())

        result = func_to_decorate(request, *args, **kwargs)

        #any post view checks to be done go here

        #return to the function to be decorated.
        return result
    return wrapper

ビューについては、次のようなものがあります。

@s_vars
def main(request, template_name='placeholder.html'):
    return render_to_response(template_name, RequestContext(request,{
           'user':user_obj
            }))

しかし、これはメソッド「main」内で user_obj にアクセスできないというエラーにつながります。私の理解では、これは内部関数であるため、「ラッパー」メソッドの下のリスト内の変数は、この内部関数「メイン」からアクセスできます。ここで何が欠けていますか?

4

3 に答える 3

2

構文

@spam
def ham():
    pass

構文と正確に同等です

def ham():
    pass
ham = spam(ham)

あなたがやっていることはなぜうまくいかないのかを明確にしていますか?


デコレータから関数に何かを渡したい場合、通常のイディオムは追加の引数を関数に送ることです。これは、正しいように見えるargspecが実際にはそうではないことを意味するため、少し厄介な場合があります。

于 2012-12-28T16:47:29.387 に答える
0

ネストされた関数は、それらが定義されているスコープからスコープ変数のみを取得し、バインディングはコンパイル時に行われます。

後でスコープ変数を追加することはできません。もちろん、単純なラッパーではできません。

于 2012-12-28T16:47:24.347 に答える
0

内部関数が呼び出される時点で、外部スコープ関数によって呼び出されるだけで、定義されていません。

その区別 (インタープリターとランタイムによっても行われる) は、スコーピングにおいて間違いなく重要です。s_vars ラッパーの dis (逆アセンブル) を見てください (または、同じ動作の簡略化された単純な例)。コードは、 の異なる値 (ここでは単なる値です) に対して再解釈されませんfunc_to_decorate

変数のリストを内部関数で使用できるようにしたい場合は、おそらくオブジェクトを渡す方が理にかなっているでしょう。ラッパーは、外部 API にそれがないことを保証できます。

于 2012-12-28T16:47:41.217 に答える