Search code examples
pythonclassmethodskeyword-argument

How do I ignore keyword arguments when they are not used in the method?


I have a class with various functions that have default values for some keywords, but values can also be specified. However, the functions use different keywords.

This is a minimum reproducible example. The actual case has functions that are more complicated and inter-related.

Example Class:

class Things(object):
    def __init__(self, **kwargs):
        self.other = 999
        self.result = self.some_fcn(**kwargs)
        self.other2 = self.some_fcn2(**kwargs)

    def some_fcn(self, x=None, y=None):
        if x is None:
            x = 7
        if y is None:
            y = 7
        return x + y

    def some_fcn2(self, z=None):
        if z is None:
            z = -1
        return self.other * z

Tests, these work:

ans = Things().some_fcn()
print("default, should be 14:", ans)
ans = Things(x=1)
print("should be 8:", ans.result)

And here on ans = Things(x=1, z=100) it fails

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-50-5e7081adb4fb> in <module>
     25 ans = Things().some_fcn(9, -2)
     26 print("should be 7:", ans)
---> 27 ans = Things(x=1)
     28 print("should be 8:", ans.result)
     29 print("***")

<ipython-input-50-5e7081adb4fb> in __init__(self, **kwargs)
      3         self.other = 999
      4         self.result = self.some_fcn(**kwargs)
----> 5         self.other2 = self.some_fcn2(**kwargs)
      6 
      7         self.__dict__.update(kwargs)

TypeError: some_fcn2() got an unexpected keyword argument 'x'

How do I ignore keyword arguments when they are not used in the method? The similar question at How to ignore extra keyword arguments in Python? says to add self.__dict__.update(kwargs) to the constructor, but that still produces the same error.


Solution

  • Use **kwargs for your inner functions as well, and then inside those functions check if the arguments exist.

    class Things(object):
        def __init__(self, **kwargs):
            self.other = 999
            self.result = self.some_fcn(**kwargs)
            self.other2 = self.some_fcn2(**kwargs)
    
        def some_fcn(self, **kwargs):
            x = 7 if 'x' not in kwargs else kwargs['x']
            y = 7 if 'y' not in kwargs else kwargs['y']
            return x + y
    
        def some_fcn2(self, **kwargs):
            z = -1 if 'z' not in kwargs else kwargs['z']
            return self.other * z