How to make **kwargs optional

3.1k views Asked by At

I have two classes that have a method with the same name, but this method uses different parameters. So I thought about using **kwargs (see example below). But one of the two methods does not require any parameter, so I get this error:

TypeError: print_smt() takes 1 positional argument but 2 were given

because it is passing an empty dictionary to the function, I suppose.

How can I solve this problem? Am I forced to use an if statement to call the function with and without parameters, or there is a better way to solve the problem?

class Bar(object):
  def print_smt(self, text):
    print(text)

class Foo(object):
  def print_smt(self):
    print("Nothing")

def test(obj, **p2):
  obj.print_smt(p2)


bar = Bar()
test(bar, text='print this')

foo = Foo()
test(foo) # This one breaks!
2

There are 2 answers

0
Charles Duffy On BEST ANSWER

When you call:

def test(obj, **p2):
  obj.print_smt(p2)

...you're passing a dictionary to print_smt(). Even if it's an empty dictionary, it's still a dictionary, and you can't pass a dictionary as an argument to something that takes no arguments.


If you want to pass through keyword arguments as keyword arguments, rather than as a single positional argument with a dictionary, then do so:

def test(obj, **p2):
  obj.print_smt(**p2)
0
Maximiliano Padulo On

You have to unpack the kwargs before passing it to the print_smt function. This works:

def test(obj, **p2):
  obj.print_smt(**p2)