Keyword arguments(**kwargs) VS Variable-length Arguments (*args) in detail

Variable-length Arguments (*args)

In large projects, sometimes we may not know the number of arguments to be passed in advance. In such cases, Python provides us the flexibility to offer the comma-separated values which are internally treated as tuples at the function call. By using the variable-length arguments, we can pass any number of arguments.

However, at the function definition, we define the variable-length argument using the *args (star) as *<variable - name >.

Consider the following example.
Example

def printme(*names):    
    print("type of passed argument is ",type(names))    
    print("printing the passed arguments...")    
    for name in names:    
        print(name)    
printme("john","David","smith","nick")    

Output:

type of passed argument is  <class 'tuple'>
printing the passed arguments...
john
David
smith
nick

In the above code, we passed *names as variable-length argument. We called the function and passed values which are treated as tuple internally. The tuple is an iterable sequence the same as the list. To print the given values, we iterated *arg names using for loop.

Keyword arguments(**kwargs)

Python allows us to call the function with the keyword arguments. This kind of function call will enable us to pass the arguments in the random order.

The name of the arguments is treated as the keywords and matched in the function calling and definition. If the same match is found, the values of the arguments are copied in the function definition.

Consider the following example.

Example 1

#function func is called with the name and message as the keyword arguments    
def func(name,message):    
    print("printing the message with",name,"and ",message)    
      
    #name and message is copied with the values John and hello respectively    
    func(name = "John",message="hello")   

Output:

printing the message with John and hello
Example 2 providing the values in different order at the calling

#The function simple_interest(p, t, r) is called with the keyword arguments the order of arguments doesn't matter in this case    
def simple_interest(p,t,r):    
    return (p*t*r)/100    
print("Simple Interest: ",simple_interest(t=10,r=10,p=1900))     

Output:

Simple Interest: 1900.0
If we provide the different name of arguments at the time of function call, an error will be thrown.

Consider the following example.

Example 3

#The function simple_interest(p, t, r) is called with the keyword arguments.     
def simple_interest(p,t,r):    
    return (p*t*r)/100    
  
# doesn't find the exact match of the name of the arguments (keywords)      
print("Simple Interest: ",simple_interest(time=10,rate=10,principle=1900))   

Output:

TypeError: simple_interest() got an unexpected keyword argument 'time'
The Python allows us to provide the mix of the required arguments and keyword arguments at the time of function call. However, the required argument must not be given after the keyword argument, i.e., once the keyword argument is encountered in the function call, the following arguments must also be the keyword arguments.

Consider the following example.

Example 4

def func(name1,message,name2):    
    print("printing the message with",name1,",",message,",and",name2)    
#the first argument is not the keyword argument    
func("John",message="hello",name2="David")   

Output:

printing the message with John , hello ,and David
The following example will cause an error due to an in-proper mix of keyword and required arguments being passed in the function call.

Example 5

def func(name1,message,name2):   
    print("printing the message with",name1,",",message,",and",name2)    
func("John",message="hello","David")        

Output:

SyntaxError: positional argument follows keyword argument
Python provides the facility to pass the multiple keyword arguments which can be represented as **kwargs. It is similar as the *args but it stores the argument in the dictionary format.

This type of arguments is useful when we do not know the number of arguments in advance.

Consider the following example:

Example 6: Many arguments using Keyword argument

def food(**kwargs):  
    print(kwargs)  
food(a="Apple")  
food(fruits="Orange", Vagitables="Carrot")  

Output:

{'a': 'Apple'}
{'fruits': 'Orange', 'Vagitables': 'Carrot'}