Packing and Unpacking Arguments in Python?

PythonServer Side ProgrammingProgramming

If you have done little-bit of programming in python, you have seen the word “**args” and “**kwargs” in python functions. But what exactly they are?

The * and ** operators did different operations which are complementary to each other depending on where we are using them.

So when we are using them in method definition, like -

def __init__(self, *args, **kwargs):
pass

Above operation is called ‘packing” as it pack all the arguments into one single variable that this method call receives into a tuple called args. We can use name other than args, but args is the most common and pythonic way of doing things. To understand why to put in a one single variable, consider below example:

Let’s assume we have a function which takes three arguments and we have a list of size 3 with us that has all the arguments for the function. Now if we simply try to pass list to the function, the call doesn’t work and through an error.

Example 1

#function which takes three argument
def func(a,b,c):
print("{} {} {}".format(a, b, c))

#list of arguments
lst = ['python', 'java', 'csharp']

#passing the list
func(lst)

Result

TypeError: func() missing 2 required positional arguments: 'b' and 'c'

Once we have ‘picked’ variable, then you do things which are not possible with a normal tuple. Args[0], args[1] and args[2] would give us the first, second and third argument respectively. If you convert the args tuple to a list then as we can do operation of modify, delete and alter items in it.

To pass these packed arguments to another method, we need to do unpacking -

def __init__(self, *args, **kwargs):
#some code here
car(VehicleClass, self).__init__(self, *args, **kwargs)
#some code below

Again we have * operator, but this time it’s in the context of a method call. What is does now is explode the args array and call the method as if each variable is independent. Below is another example to get clear understanding -

Example 2

def func1(x, y, z):
print(x)
print(y)
print(z)

def func2(*args):
#Convert args tuple to a list so we can do modification.
args = list(args)
args[0] = 'HTML'
args[1] = 'CSS'
args[2] = 'JavaScript'
func1(*args)

func2('Python', 'Java', 'CSharp')

Result

HTML
CSS
JavaScript

From above output, we are able to change all three arguments before passing them off to func1.

Similarly we can solve the TypeError message found in example1.

Example:1_1

#function which takes three argument
def func(a,b,c):
print("{} {} {}".format(a, b, c))

#list of arguments
lst = ['python', 'java', 'csharp']

#passing the list
func(*lst)

Result

python java csharp

So incase we don’t know how many arguments need to be passed to a python function, we can use packing to pack all arguments in a tuple.

#Below function uses packing to sum unknown number of arguments
def Sum(*args):
sum = 0
for i in range(0, len(args)):
   sum = sum + args[i]
return sum

#Driver code
print("Function with 2 arguments & Sum is: \n",Sum(9, 12))
print("Function with 5 arguments & Sum is: \n",Sum(2, 3, 4, 5, 6))
print("Function with 6 arguments & Sum is: \n",Sum(20, 30, 40, 12, 40, 54))

Result

Function with 2 arguments & Sum is:
21
Function with 5 arguments & Sum is:
20
Function with 6 arguments & Sum is:
196

Below is another program to demonstrate the use of packing and unpacking both:

#function with three arguments
def func1(x,y,z):
print("Argument One: ",x)
print("\nArgument Two: ",y)
print("\nArgument Three: ",z)

#Packing- All arguments passed to func2 are packed into tuple *args
def func2(*args):
#To do some modification, we need to convert args tuple to list
args = list(args)

#Modifying args[0] & args[1]
args[0] = 'Hello'
args[1] = 'TutorialsPoint'

#Unpacking args and calling func1()
func1(*args)

#Driver code
func2("I", "Love", "Coding")

Result

Argument One: Hello

Argument Two: TutorialsPoint

Argument Three: Coding

Use ** for dictionaries

# Program to demonstrate unpacking of dictionary items using **
def func(x,y,z):
print("Dicionary first item: ",x)
print("\nDictionary second item: ",y)
print("\nDictionary third item: ",z)
d = {'x': 27, 'y': 54, 'z': 81}
func(**d)

Result

Dicionary first item: 27

Dictionary second item: 54

Dictionary third item: 81

Applications

  • Used in socket programming where we need to send unknown(infinite) number of requests to server.

  • Used in web frameworks like django to send variable arguments to view functions.

  • Used in wrapper functions that require us to pass in variable arguments.

raja
Published on 02-May-2019 13:50:09
Advertisements