1

我有一個裝飾器,它需要一個authToken並提供用user_id裝飾的函數。這個想法是停止每個用戶特定的功能,而不必查找他們的用戶對象。裝飾器:TypeError:在函數調用時獲得了多個關鍵字參數值<變量名稱>

我已經使用* pargs和** kwargs使裝飾通用,並與任何其他參數一起使用函數。

但是,當我調用裝飾函數不僅僅是裝飾器設置的參數時,我得到錯誤:TypeError: changeUsername() got multiple values for keyword argument 'userId'

有人知道爲什麼會發生這種情況嗎?我在下面貼了一個簡單的例子。

users = ["Name_1", "Name_2", "Name_3"] 

def pwapi_auth(func): 
    def inner(authToken, *pargs, **kwargs): 
     users = {'a':0, 
       'b':1, 
       'c':2} 
     userId = users[authToken] 
     return func(userId = userId, *pargs, **kwargs) 
    return inner 

@pwapi_auth 
def getUsername(userId): 
    return users[userId] 

@pwapi_auth 
def changeUsername(userId, newName): 
    users[userId] = newName 

print getUsername('b') 
changeUsername('b', 'New_Person') # <-- Error occurs on this call 

謝謝!

+1

你的第二個例子是不工作的代碼,能否請您粘貼的工作片段 – AlokThakur

+1

別擔心,我現在已經明白 - 超做一些東西來簡化。 –

回答

1

在你的代碼片段中,python會在userId的位置參數和關鍵字參數之間混淆。追加所有的參數pargs解決這個 -

def pwapi_auth(func): 
    def inner(authToken, *pargs, **kwargs): 
     # ... 
     users = {'a':0, 
       'b':1, 
       'c':2} 
     userId = users[authToken] 
     return func(*((userId,)+pargs), **kwargs) 
    return inner 
>>> print getUsername('b') 
Name_2 
>>> changeUsername('b', 'New_Person') 
>>> print getUsername('b') 
New_Person 
+1

你不需要那裏的列表;只需返回'func(*((userId,)+ pargs),** kwargs)' – zondo

+1

感謝您的輸入@zondo,我在尋找類似的東西,這是更好的方法。我會更新我的回答 – AlokThakur

+0

感謝您的答案球員 - 似乎工作。我現在的問題是:我已經得到了上面的例子(添加到問題的底部),它使用一個不需要編輯pargs或pwargs的類 - 它只是將userId作爲位置參數直接放入返回的函數中。爲什麼這會起作用,而我最初的例子不是? –

相關問題