Search code examples
pythonkeyword-argument

Python function: how to use the argument in kwargs


When writing functions with **kwargs, the syntax becomes not as clean as without it. For example

def func(x, y):
    print(x + y)

will become

def func(**kwargs):
    print(kwargs["x"] + kwargs["y"])

Any suggestions to make calling kwargs nicer and more clean?


Solution

  • argparse mentioned in the other answer uses kwargs a lot. It gives a lot of flexibility when handling a large number optional parameters, but the syntax is not 'simple. You need to handle the case where the user does not provide a value. The dictionary get is good for that:

    In [241]: def func(**kwargs): 
         ...:     print(kwargs) 
         ...:     x = kwargs.get('x',0) 
         ...:     y = kwargs.get('y',0) 
         ...:     return x + y 
         ...:      
         ...:                                                                       
    In [242]: func(x=1, y=2)                                                        
    {'x': 1, 'y': 2}
    Out[242]: 3
    In [243]: func(**{'x':1, 'y':2})                                                
    {'x': 1, 'y': 2}
    Out[243]: 3
    

    Also use if 'x' in kwargs: or for key in kwargs:

    With keyword parameters, you can use the same **dict style of input:

    In [244]: def func(x=0, y=2): 
         ...:     return x + y                                                                       
    In [245]: func(**{'x':1, 'y':2})                                                
    Out[245]: 3
    

    You could unpack the kwargs with:

    In [246]: def func(**kwargs): 
         ...:     x, y = kwargs.values() 
         ...:     return x + y 
         ...:                                                                       
    In [247]: func(**{'x':1, 'y':2})                                                
    Out[247]: 3
    

    but in that case you might as well use *args:

    In [248]: def func(*args): 
         ...:     x, y = args 
         ...:     return x + y 
         ...:                                                                       
    In [249]: func(1,2)                                                             
    Out[249]: 3
    

    Part of the code for argparse.Namespace:

    class Namespace(_AttributeHolder):
        def __init__(self, **kwargs):
            for name in kwargs:
                setattr(self, name, kwargs[name])
    

    This converts the dictionary keys into object attributes. argparse also notes that you can go the other direction with vars(args), getting a dictionary from an object's attributes.