我们已经实现了一个扭曲的web API。Python装饰器内部调用错误函数
为了处理auth,我们使用了一个装饰器来包装一些路径。
@requires_auth(roles=[Roles.Admin])
def get_secret_stuff(request):
return 42
requires_auth
包装实现如下。
def requires_auth(roles):
def wrap(f):
def wrapped_f(request, *args, **kwargs):
# If the user is authenticated then...
return f(request, *args, **kwargs)
return wrapped_f
return wrap
的问题是,如果有多个路由与这个装饰,再到 调用其中的任何导致被装饰被称为最新的路线。
这显然不是我想要的,并且反驳我对装饰者应该如何工作的理解。 我加了一些打印语句代码,试图弄明白:
def requires_auth(roles):
def wrap(f):
print(f) # This shows that the decorator is being called correctly once per each
# route that is decorated
def wrapped_f(request, *args, **kwargs):
# If the user is authenticated then...
return f(request, *args, **kwargs)
return wrapped_f
return wrap
在情况下,它是很重要的,我现在用扭曲的inlineCallbacks其中一些路线,以及为所有的双绞线网络的@app.route(url, methods)
装饰这些路线。
谢谢您的阅读:)
编辑: 我删除默认的参数传递给构造有人告诉我这是一个坏主意:)
编辑:这里是一个小例子,说明了问题:
from klein import Klein
import json
app = Klein()
def requires_auth(roles):
def wrap(f):
print('inside the first clojure with f=%s' % str(f))
def wrapped_f(request, *args, **kwargs):
print('inside the second closure with f=%s' % str(f))
return f(request, *args, **kwargs)
return wrapped_f
return wrap
@app.route('/thing_a')
@requires_auth(roles=['user'])
def get_a(request):
return json.dumps({'thing A': 'hello'})
@app.route('/thing_b')
@requires_auth(roles=['admin'])
def get_b(request):
return json.dumps({'thing B': 'goodbye'})
app.run('0.0.0.0', 8080)
要去航线使用可变一个从route_b
不应该'wrap'返回'wrapped_f'? – Max
对不起,我错误地把它留下了,更新了。 – avoid3d
您有'@ requires_auth'但是'def require_auth' ...注意's' – Eric