johnnygear
johnnygear

Reputation: 93

Python 3: Best practice way to validate/parse **kwargs?

I am trying to learn more about Python - I am using 3.6.3 currently.

What is the best practice for argument validation/parsing when using kwargs?

Or, what is the best practice for argument validation/parsing without kwargs?

class foo:
  def __init__(self, **kwargs):
    if 'a' in kwargs:
      self.a = kwargs['a']
    else:
      self.a = 0

class bar(foo):
  def __init__(self, **kwargs):
    super().__init__()
    if 'x' in kwargs:
      self.x = kwargs['x']
    else:
      self.x = 23

# b and y are undefined, but my classes use kwargs - what is the best practice for validating / parsing dynamic arguments?
test = bar(b=1,y=24)

Upvotes: 7

Views: 7115

Answers (2)

Joran Beasley
Joran Beasley

Reputation: 113978

class Foo:
   def __init__(self,a=0):
       self.a = a

class Bar(Foo):
    def __init__(self,b=21,**kwargs):
        self.b = b  # accept whatever you want for this child
        Foo.__init__(self,**kwargs) # pass remaining kwargs down the line

does exactly what your Foo class does and is much more clear

most problems with using kwargs come from the fact that its not at all self documenting ... I have no idea what arguments can and should be supplied for neither Foo or Bar where as explicitly declared arguments with default values make it very clear what options are available to pass into the functions

Upvotes: 2

Hat
Hat

Reputation: 570

You can pass a default value to get() for keys that are not in the kwargs dictionary:

def __init__(self, **kwargs):
    self.a = kwargs.get("a", 0)
    self.x = kwargs.get("x", 23)
    # etc.

Alternatively if you want any value in kwargs to be set as an instance variable of your class, you could do:

def __init__(self, **kwargs):
    for k, v in kwargs.items():
        self.__setattr__(k, v)

Upvotes: 6

Related Questions