13

ここと同じ方法でデコレータを実装し ましたFlaskで引数(承認用)を使用してPythonデコレータ関数を作成する方法 ですが、問題はまだ解決されていません...

私はデコレータでこの機能を持っています

@blueprint.route('<var>')
@blueprint.my_decorator(var)
def function(var):
    do stuff

そして私はこのエラーを受け取ります

NameError: global name 'var' is not defined

どうすればこれを解決できますか?


アップデート

ブループリントは、ブループリントクラスを継承するクラスです。だから私はメソッドを実装しました

def my_decorator(self, fn):
    @wraps(fn)
    def decorator(*args, **kwargs):
        value = kwargs['value']
        # do stuff with value
        return fn(*args, **kwargs)
    return decorator

しかし、それでも値は不明なキーです...

4

1 に答える 1

24

デコレータはインポート時に実行され、基本的には構文糖衣です。

@foo(bar)
def baz():
    return 'w00t!'

と同等です

def baz():
   return 'w00t!'
baz = foo(bar)(baz)

したがって、上記の例では、変数barは、引数としてデコレータに渡される前に、このモジュールのグローバルスコープに存在する必要があります。それはあなたが持っているエラーがあなたに言うことです。


アップデート

以下の説明に基づいて、質問のコードは、ビュー関数に渡された値をインターセプトし、それを使用して何かを実行する必要があります。これを示す例を次に示します。

from functools import wraps
from flask import Flask, abort

app = Flask(__name__)

def foobar(fn):
    @wraps(fn)
    def decorated_view(*args, **kwargs):
        value = kwargs['value']
        # Do something with value...
        if value == 'foobar':
            abort(400)
        return fn(*args, **kwargs)
    return decorated_view

@app.route('/<value>')
@foobar
def view(value):
    return value
于 2012-12-18T12:24:04.107 に答える