Python **在父和子构造函数中的kwargs

时间:2014-08-05 03:56:34

标签: python inheritance

如果我按如下方式编写继承关系:

class Pet(object):
  def __init__(self, n):
    print n

class Dog(Pet):
  def __init__(self, **kwargs):
    Pet.__init__(self, 5)

然后输出为5。但是,如果我想这样做:

class Pet(object):
  def __init__(self, **kwargs):
    if not "n" in kwargs:
      raise ValueError("Please specify the number I am to print")
    print kwargs["n"]

class Dog(Pet):
  def __init__(self, **kwargs):
    Pet.__init__(self, kwargs)

然后我收到错误TypeError: __init__() takes exactly one argument (two given)

如何以这种方式在继承链上传递额外的参数?

2 个答案:

答案 0 :(得分:4)

只需将参数作为关键字参数传递:

class Pet(object):
  def __init__(self, **kwargs):
    if not "n" in kwargs:
      raise ValueError("Please specify the number I am to print")
    print kwargs["n"]

class Dog(Pet):
  def __init__(self, **kwargs):
    Pet.__init__(self, **kwargs)

但是,您应该使用super而不是硬编码超类。

Dog的定义更改为(Python 2.X):

class Dog(Pet):
  def __init__(self, **kwargs):
    super(Dog, self).__init__(**kwargs)

在Python 3.X中它更好,只是:

class Dog(Pet):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)

答案 1 :(得分:1)

想出来:使用Pet.__init__(self, **kwargs)

它被称为"拆包"它将字典kwargs转换为参数=值对的列表。

然后父构造函数中的**kwargs能够处理它们。只是传递一个字典是行不通的,因为构造函数中的**kwargs期望一堆参数=值对,但我只是传递了一个值,即来自孩子的字典kwargs