2017-06-16 45 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