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作为位置参数直接放入返回的函数中。为什么这会起作用,而我最初的例子不是? –

相关问题