我需要为Flask路线功能添加一个python装饰器(基本上我编辑了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
并像这样使用就可以了:
@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
我对装饰器的东西很新,我该如何纠正这个错误?
答案 0 :(得分:8)
你有两个包装函数,你只需要一个。请注意,每个包装函数都接受一个参数。这应该是发生了什么的线索。
你有:
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
。这显然不是你想要的。您希望wrapper1
返回。在您的回答中,解决方案是删除外部包装器(def decorator(takes_a_function):
@wraps(takes_a_function)
def wrapper(*args, **kwargs):
# logic here
return takes_a_function(*args, **kwargs)
return wrapper
):
{{1}}
答案 1 :(得分:4)
好的,我通过阅读@ will-hart
给出的答案Route to view_func with same decorators "flask"来解决这个问题我只是删除def wrapper(f)
,现在一切似乎都很好。在没有语法错误。
def requires_admin(f):
@wraps(f)
def wrapped(*args, **kwargs):
#if blah blah:
#return blah blah
return f(*args, **kwargs)
return wrapped
因为我是装饰师的新手,我不知道为什么。但希望这可以帮助其他人。