What does this mean in Python: *args, **kwargs?
Tags: python, machinelearning, django, flask
Published: 2020-03-01 11:26:22

If you are new to python one stumbling block you will face during your learning experience is understanding the **\*args** and **\**kwargs** magical variables. I also had a hard time figuring how they work 😅 when I started.
```python
 def args_kwargs(*args, **kwargs):
      pass
```
Python **\*args** and **\**kwargs** arguments are everywhere. You can find them in the source code of one of the most popular Python frameworks (Django). 
The variable **\*args** and **\**kwargs** can be written in any form. e.g **\*vars** and **\**kvars** are also valid. Only the * (asterisk) is necessary.
In this lesson, I will explain what they are and how to use them 😎.

###Using **\*args** in a function definition:
 **\*args** can be used in function definitions. They allow the user to call a function with a number of variable arguments. Variable here means that you do not know beforehand how many arguments that can be passed to your function by the user so in this case, you use the **\*args** keywords. What **\*args** allows you to do is take in more arguments than the number of formal arguments that you previously defined. Internally they are represented using **tuple** data structure.
Note that before the variable number of arguments, zero or more normal arguments may occur. 

An interesting example for usage of **\*args**:
```python
def positions(first_arg, *args):
    print(f"Type of *args is {type(args)}") #print type of args
    print(f"first position arg:{first_arg}")
    for arg in args:
        print(f"another arg through *args: {arg}")

positions('first','second','third','forth')
#results
Type of *args is <class 'tuple'>
first position arg:first
another arg through *args: second
another arg through *args: third
another arg through *args: forth
```

###Using **\**kwargs** in a function definition:
The special syntax **\**kwargs** in a function definition is used to pass a keyworded, variable-length argument list.
**\**kwargs** allows you to pass keyworded variable length of arguments to a function. Internally, they are represented using dictionary data structure.
Here is a basic example to explain this concept:
```python
def items(**kwargs):
    print(f"Type of **kwargs is {type(kwargs)}") #print type of **kwargs
    #iterating over the keyword argument
    if kwargs is not None:
        for key, value in kwargs.items():
            print(f"{key} = {value}")
 
items(a="basket", b="plate", c="soap")
#results
Type of **kwargs is <class 'dict'>
a = basket
b = plate
c = soap
```
*From the above examples, we can see that using *args and *kwargs gives our function definitions the flexibility of accepting an unlimited number of arguments.
Let's look at some examples of using **\*args** and **\**kwargs** when calling a function.

**\*args** can be used to unpack values from iterable objects(list, tuple) in Python.
```python
def test_args_kwargs(arg1,arg2,arg3):
     print(f"{arg1},{arg2},{arg3}")

#using tuple
test_args_kwargs(*('first','second','third'))
#OR
test_args_kwargs(*['first','second','third'])

#results
first,second,third #unpacking tuple
first,second,third #unpacking list

```
While the **\**kwargs** can only be used to unpack a dictionary.
```python
# now with **kwargs:
kwargs = {"arg1": "first", "arg2": "second","arg3":"third"}
test_args_kwargs(**kwargs)
#results
arg1: first
arg2: second
arg3: third
```
###Order of using *args **kwargs and formal args
The correct order for your parameters is:
standard arguments
*args arguments
**kwargs arguments

Let's see how to combine the various types of parameter:
```python
#right
def my_func(args, *args, **kwargs):
    pass

#wrong
def my_func(args, **kwargs, *args):
    pass

```
**Bonus**
We can also use * to collect values during an assignment.
```python
first,*others = ["first","second","third"]
print(first,others, sep="\n")
#results
first
['second', 'third']
```
I hope you now have a clear understanding of how to use **\*args** and **\**kwargs** when defining or calling a function in Python.
If you have any questions, please leave your comments below. 

Next week, I will explain how to use Multithreading and Multiprocessing to speed up your programs :). Please follow me and turn on your notification. Thank you!
Happy coding! ✌