Python ** kwargs in parent and child constructor

If I write an inheritance relationship like this:

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

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

      

Then there will be a way out 5

. If, however, I wanted to do:

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)

      

Then I get the error TypeError: __init__() takes exactly one argument (two given)

How can I pass additional arguments to the inheritance chain this way?

+3


source to share


2 answers


Just pass the arguments down as keyword arguments:

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)

      

However, you should use the super

superclass, not hardcoding.

Change the definition Dog

to (Python 2.X):



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

      

And in Python 3.X it's better, just:

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

      

+2


source


Figured out: use Pet.__init__(self, **kwargs)

It's called "unpacking" and converts the dictionary kwargs

into a list of argument = value pairs.



Then **kwargs

the parent constructor can handle them. Just passing in a dictionary won't work because it **kwargs

expects a pair of argument pairs = value in the constructor, but instead I just passed one value to it, a dictionary kwargs

from the child.

+1


source







All Articles