Python装饰与烧瓶 [英] Python decorator with Flask

查看:292
本文介绍了Python装饰与烧瓶的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要添加一个python装饰器到Flask路由函数,(基本上我编辑了这里的代码) / b>

  def require_admin(f):
def wrapper(f):
@wraps(f)
def包裹(* args,** kwargs):
#if不是admin:
#return render_template('error.html')
返回f(* args,** kwargs)
返回包装
返回包装

  @ app.route('/ admin / action')
@requires_admin
Admin Admin() :
#NO错误如果没有参数

但是像这样使用会产生错误:

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

在Flask 0.10中,我得到这样的错误从瓶0.9到0.10,并在佛罗里达州sk $ 0.9没有这样的语法错误):

$ $ $ $ $ $ $ $ $ $ $ $ $ b文件/ usr / local / lib / python2.6的/ DIST-包/瓶-0.10.1-py2.6.egg /瓶/应用程序。
py,第1013行,在装饰器
self.add_url_rule(规则,端点,f,**选项)
文件/usr/local/lib/python2.6/dist-packages /Flask-0.10.1-py2.6.egg/flask/app。
py,第62行,在wrapper_func
返回f(self,* args,** kwargs)
文件/usr/local/lib/python2.6/dist-packages/Flask -0.10.1-py2.6.egg /烧瓶/应用程序。
py,第984行,在add_url_rule
'现有端点函数:%s'%端点)
AssertionError:视图函数映射覆盖现有的端点函数
on:wrapper

我对装饰器的东西很新,怎么改正这个错误? $ b

解决方案

你有两个包装函数,你只需要一个包装函数,注意每个包装函数都有一个参数,这应该是一个线索。

您有:

  def装饰器(take_a_function):
def wrapper1(take_a_function):
def wrapper2(* takes_multiple_arguments):
#do stuff
return take_a_function(* takes_multiple_arguments)

wrapper2
返回wrapper1

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

  @decorator 
def my_function(* takes_multiple_arguments) :
pass

这相当于:

  def my_function(* takes_multiple_arguments):
pass
$ b $ my_function = decorator(my_function)

但做装饰器(my_function)返回 wrapper1 ,如果你记得有一个
参数, take_a_function 。这显然不是你想要的。你需要返回 wrapper2 。在你的答案中,解决方案是删除外部包装( wrapper1 ):

  def decorator(takes_a_function):
@wraps(takes_a_function)
def包装器(* args,** kwargs):
#logic这里
return takes_a_function(* args ,** kwargs)

返回包装


I need to add a python decorator to Flask route functions, (basically I edited the code from here)

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

and use it like this will be OK:

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

But use it like this will have error:

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

In Flask 0.10, I get errors like this (I just updated from Flask 0.9 to 0.10, and in Flask 0.9 there is no grammar error like this):

    @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

I am pretty new to the decorator stuff, how do I correct this error?

解决方案

You have two wrapper functions where you only need one. Notice that each wrapper function takes one argument. This should be a clue as to what is happening.

You have:

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

When you decorate a function with it:

@decorator
def my_function(*takes_multiple_arguments):
   pass

This is equivalent to:

def my_function(*takes_multiple_arguments):
   pass

my_function = decorator(my_function)

but doing decorator(my_function) returns wrapper1, which if you recall takes one argument, take_a_function. This is clearly not what you want. You want wrapper2 returned. As in your answer, the solution is to remove the outer wrapper(wrapper1):

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

    return wrapper

这篇关于Python装饰与烧瓶的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆