Python装饰与烧瓶 [英] Python decorator with Flask
问题描述
我需要添加一个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屋!