2017-06-16 60 views
1

我试图添加一个access_rights修饰器到我的Bottle应用程序来检查访问路线时的权限。但是,它没有获取装饰函数的参数,这会在尝试再次调用装饰函数时导致错误。修饰器没有得到参数

下面是一个使用装饰的代码示例:

@route('/users') 
@access_rights({'POST': ['admin']}) 
def users(user): 
    pass 

user参数来源于瓶插件,我写的会从与请求传递令牌用户。这是我目前装饰:

def access_rights(permissions): 
    def decorator(f):  
     def wrapper(*args, **kwargs): 
      # Check permissions rights here (not implemented yet) 

      return f(*args, **kwargs) 

     return wrapper 

    return decorator 

有了这个,我得到TypeError: users() takes exactly 1 argument (0 given)GET /users时,意味着argskwargs都是空的。然而,当我改变装饰如下,它的工作原理:

def access_rights(permissions): 
    def decorator(f): 
     return f 

    return decorator 

我还没有装饰做了很多,但是从我的理解,上述两种实现应该调用users功能,其原有的参数,但对于第一个没有得到参数的原因。这是为什么?

+1

此代码适用于我。如果你的第二个装饰器语法有效,那么这意味着你没有使用它的参数:即你只是'@ access_rights'而不是'@access_rights(whatever)'。 –

+0

也许在某处检查函数名称?在这种情况下,包装器上方的@ functools.wrap(f)应该有所帮助。 – Artyer

+0

你使用py2还是py3?我不认为这会产生巨大的影响,但我很好奇。 –

回答

0

您的路由处理函数users需要一个参数。

但是你的装饰者,access_rights,你绕,没有通过user帕拉姆;它只是传递它接收到的任何参数(在这种情况下,没有任何参数,因此错误消息的“0给定”部分)。

一个例子应该有助于澄清。这里有一个小而完整的工作程序,根据您的原始代码:

from bottle import route, Bottle 

app = Bottle() 

def access_rights(permissions): 
    def decorator(f): 
     def wrapper(*args, **kwargs): 
      # Check permissions rights here (not implemented yet) 

      the_user = 'ron' # hard-coded for this example 

      return f(the_user, *args, **kwargs) 

     return wrapper 

    return decorator 


@app.route('/users') 
@access_rights({'POST': ['admin']}) 
def users(user): 
    return ['hello, {}'.format(user)] 


app.run(host='127.0.0.1', port=8080, debug=True) 

注意,我做出的唯一实质性的改变是有access_rights实际传递的路线用户PARAM。 (它如何决定用户自然是由你决定的 - 大概是你在评论中提到的“尚未实现”的部分)。

希望有帮助!

+0

我明白'user'参数没有被传递,但这不是我的装饰器的工作。正如我的问题所述,该'user'参数是由插件生成并传递的,所以它不应该由装饰器处理。对我来说没有任何意义的是,直接返回'f',而不是''wrapper',它只是通过传递的参数调用'f',并不会产生相同的结果。我在这里错过了什么? – PLPeeters