Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using both explicit arguments and **kwargs in python

Tags:

python

I have this piece of code:

kwargs_input = {"name": "lala", "age": 25, "postcode": 17867}

def print_kwargs(**kwargs):
    for k,v in kwargs.items():
        print(k,v)

def func_print(name="lolo", age=56, **kwargs):
    print_kwargs(**kwargs)

print(func_print(**kwargs_input))

It prints:

postcode 17867
None

I have two questions:

  1. Why name and age are not printed? I was expecting to override the default value of name (lolo) and age (56) with the arguments passed as **kwargs_input. Is that possible?
  2. Where does None come from?
like image 672
eng2019 Avatar asked Jun 30 '26 20:06

eng2019


2 Answers

  1. Neither name nor age are printed, because they have been removed from kwargs during the function call. Inside the function call you have access to both name and age through those variables. kwargs will contain the rest of the 'variables'.
  2. The None is returned from func_print() by default and your print(func_print()) prints it out.
like image 194
quamrana Avatar answered Jul 03 '26 10:07

quamrana


name and age aren't packed into the first kwargs in func_print() therefore aren't passed further into other functions. Or in other words, it's not collecting all arguments, it's only collecting arguments that are unspecified, "dangling", so that it doesn't throw an error. Similar to Varargs in C.

None comes from the func_print()'s return as it's the default value of any function.

For example:

def func():
    ...  # check help(...) and type(...)
    # implicit "return None"

def func():
    pass
    # implicit "return None"

def func():
    return
    # implicit "return None"

def func():
    # explicit return None
    return None

What you can however do is something that's common in JavaScript nowadays, send an object as an argument. Fortunately, you don't need to create and pass a custom object instance or anything like that because just **kwargs itself is a syntax that creates a dictionary (alternatively *args creates a tuple), so an object's instance preserving the arguments. (Similarly, you can use *args for positional arguments, more on that here).

From that you can do this:

def other(**kwargs):
    print(kwargs)

def func(**kwargs):
    print(kwargs.get("name", "lolo"))
    other(**kwargs)

print(func(name=123, hello="world"))
# 123
# {'name': 123, 'hello': 'world'}
# None
print(func(hello="world"))
# lolo
# {'hello': 'world'}
# None
like image 37
Peter Badida Avatar answered Jul 03 '26 11:07

Peter Badida



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!