装饰器:TypeError:“在函数调用中为关键字参数<variable name =”“>”获取了多个值

时间:2016-02-13 18:34:36

标签: python functional-programming decorator python-decorators

我有一个装饰器,它接受一个authToken并提供用user_id装饰的函数。我们的想法是停止每个用户特定的功能,使其不必查找用户对象。

我使用* 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 个答案:

答案 0 :(得分:2)

在你的代码片段中,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