带Flask的Python装饰器

詹姆斯·金

我需要在Flask路由函数中添加一个python装饰器,(基本上我是从这里编辑代码的

def requires_admin(f):
    def wrapper(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            #if not admin:
                #return render_template('error.html')
            return f(*args, **kwargs)
        return wrapped
    return wrapper

并像这样使用它就可以了:

@app.route('/admin/action')
@requires_admin
def AdminAction():
#NO error if NO parameter

但是像这样使用它会出现错误:

@app.route('/admin/action/<int:id>')
@requires_admin
def AdminAction(id):

在Flask 0.10中,我收到这样的错误(我刚刚从Flask 0.9更新到0.10,而在Flask 0.9中没有这样的语法错误):

    @requires_admin
  File "/usr/local/lib/python2.6/dist-packages/Flask-0.10.1-py2.6.egg/flask/app.
py", line 1013, in decorator
    self.add_url_rule(rule, endpoint, f, **options)
  File "/usr/local/lib/python2.6/dist-packages/Flask-0.10.1-py2.6.egg/flask/app.
py", line 62, in wrapper_func
    return f(self, *args, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/Flask-0.10.1-py2.6.egg/flask/app.
py", line 984, in add_url_rule
    'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint functi
on: wrapper

我对装饰器工具还很陌生,如何纠正此错误?

乔尔·科内特(Joel Cornett)

您有两个包装器功能,而您只需要其中一个。请注意,每个包装器函数都带有一个参数。这应该是正在发生的事情的线索。

你有:

def decorator(take_a_function):
    def wrapper1(take_a_function):
        def wrapper2(*takes_multiple_arguments):
           # do stuff
           return take_a_function(*takes_multiple_arguments)

        return wrapper2
    return wrapper1

当您用它装饰一个函数时:

@decorator
def my_function(*takes_multiple_arguments):
   pass

这等效于:

def my_function(*takes_multiple_arguments):
   pass

my_function = decorator(my_function)

但要进行decorator(my_function)返回wrapper1,如果您还记得,则返回一个参数take_a_function这显然不是您想要的。你想wrapper2回来。如您的答案所示,解决方案是删除外部wrapper(wrapper1):

from functools import wraps

def decorator(takes_a_function):
    @wraps(takes_a_function)
    def wrapper(*args, **kwargs):
        # logic here
        return takes_a_function(*args, **kwargs)

    return wrapper

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章