Home > OS >  passing **kwargs to a de-referencing function
passing **kwargs to a de-referencing function

Time:01-04

Hope the title is conveying the correct information.

My problem is that I don't understand why call kwarg_function(some_func, a=1, b=2, c=3) fails. I would have thought that as 'c' isn't referenced with some_func() it would simply be ignored. Can anyone explain why 'c' isn't simply ignored.

def kwarg_function(function, **kwargs):
    print(kwargs)
    function(**kwargs)

def some_func(a, b):
    print(f"type: {type(a)} values: {a}")
    print(f"type: {type(b)} values: {b}")


kwarg_function(some_func, a=1, b=2)         # called successfully

kwarg_function(some_func, a=1, b=2, c=3)    # fails with unexpected keyword arg 'c'   

CodePudding user response:

Think of the ** as "unpack what's on my right side as keyword arguments" in this case.

def foo(a,b,**kwargs):
    # This will take any number of arguments provided that starting from the 3rd one they are keyword args


# Those are equivalent (and working) calls
foo(1,2, x = 7)
foo(1,2, **{"x":7})
# Those will fail
foo(1,2,7)
foo(1,2, {"x":7})

The function you declared expects 2 arguments

def some_func(a, b):

And you are calling it with three under the hood, because this:

kwarg_function(some_func, a=1, b=2, c=3)    # fails with unexpected keyword arg 'c'   

Does this (inside kwarg_function body):

funtion(a=1,b=2,c=3)

CodePudding user response:

In python, * and ** are for unpacking iterables. They don't consider what's are in them, and just unpack whatever you pass in them.

You can find more info about it in this link.

So, when you pass a=1, b=2, c=3, ... as kwargs to your kwargs_function, you will get them as kwargs param, regardless of what you have passed.

And then, when you pass **kwargs to another function, all of your data would be passed to your another function, regardless of what's in that.

If you want your some_func be more flexible with your data and accept whatever you pass to it, you can add **kwargs param to it too:

def some_func(a, b, **kwargs):
    print(f"type: {type(a)} values: {a}")
    print(f"type: {type(b)} values: {b}")
  • Related