13

我以与此处相同的方式实现了一个装饰器 How to make a python decorator function in Flask with arguments (for authorization) 但问题仍未解决...

我有装饰器的这个功能

@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 回答