** kwargs和默认参数

时间:2018-08-21 01:53:31

标签: python python-2.7 kwargs

class Klass:
  def __init__(self, **kwargs):
    self.func(variable=True, **kwargs)

  def func(self, variable=True, **kwargs):
    print(variable)


if __name__ == '__main__':
  Klass(variable=False)

我想知道为什么我得到TypeError: func() got multiple values for keyword argument 'variable'

我认为它应该打印False,因为我将variable的默认值覆盖了False并一路传递了kwargs

4 个答案:

答案 0 :(得分:9)

您不能两次传递相同的参数,而variable=True, **kwargs正是在kwargs包含variable的密钥的情况下进行的;在这种情况下,您有效地拨打了电话self.func(variable=True, variable=False),这显然是错误的。假设您无法将variable作为单独的参数接收,例如:

def __init__(self, variable=True, **kwargs):
    self.func(variable, **kwargs)

然后另一种方法是在kwargs dict本身中设置默认值:

def __init__(self, **kwargs):
    kwargs.setdefault('variable', True)  # Sets variable to True only if not passed by caller
    self.func(**kwargs)

在Python 3.5中,使用PEP 448's additional unpacking generalizations,您可以安全地将其单行为:

def __init__(self, **kwargs):
    self.func(**{'variable': True, **kwargs})

因为在创建新的dict时重复的密钥是合法的(仅保留最后一次出现的密钥),所以您可以创建具有唯一映射的全新dict,然后立即将其解压缩。

答案 1 :(得分:0)

因为要放入可变参数,所以python不知道哪个是正确的,所以会引发错误

更清晰的示例:

df[!grepl(paste(lookm, collapse="|"), df$Main),]

答案 2 :(得分:0)

class Klass:
  def __init__(self, **kwargs):
    self.func(**kwargs)

  def func(self, variable=True, **kwargs):
    print(variable)


if __name__ == '__main__':
  Klass(variable=False)

这应该有效。您正在设置默认值“ True”,并将参数“ False”传递给一个关键字“ variable”。

答案 3 :(得分:0)

声明类Klass的对象时,

Klass(variable=False)

variable被解析为关键字自变量(kwargs),而关键字自变量始终是dict。因此,在__init__方法中,您可以找到kwargs就像

{'variable': False'}

self.func(variable=True, **kwargs)

双星号表示将dict中的所有内容解析为关键字参数。从技术上讲,这条线等于

self.func(variable=True, **{'variable': False'})

并等于

self.func(variable=True, variable=False)

这就是为什么您得到TypeError的原因。

这可能是您要寻找的东西

class Klass:
  def __init__(self, **kwargs):
    self.func(**kwargs)

  def func(self, variable=True, **kwargs):
    print(variable)

if __name__ == '__main__':
  Klass(variable=False)