|
| 1 | +# Advanced Python |
| 2 | +## Functions as First class objects |
| 3 | +Functions in Python are so called first class objects, which means they can be treated as variables, viz. functions can be used as arguments or they can be returned using the return keyword. |
| 4 | + |
| 5 | +**Example** |
| 6 | + |
| 7 | +```python |
| 8 | +def func1(): |
| 9 | + def func2(): |
| 10 | + print("Printing from the inner function, func2") |
| 11 | + return func2 |
| 12 | + |
| 13 | +``` |
| 14 | +Assigning func1 to function_call object |
| 15 | +```python |
| 16 | +function_call=func1() |
| 17 | +``` |
| 18 | +Calling the function |
| 19 | +```python |
| 20 | +>> function_call() |
| 21 | +``` |
| 22 | +**Output** |
| 23 | +``` |
| 24 | +Printing from the inner function, func2 |
| 25 | +``` |
| 26 | +Here we have seen the use of function as a first class object, func2 was returned as the result of the execution of the outer function, func1. |
| 27 | + |
| 28 | +## *args |
| 29 | +\* is an iterating operator used to unpack datatypes such as lists, tuples etc. |
| 30 | +**For example** |
| 31 | +```python |
| 32 | +tuple1=(1,2,4,5,6,7) |
| 33 | +print(tuple1) |
| 34 | +print(*tuple1) |
| 35 | +``` |
| 36 | +In the above we have defined a tuple called tuple1 with the items (1,2,4,5,6,7). |
| 37 | +First we print normally and the output for that is: |
| 38 | +``` |
| 39 | +(1, 2, 4, 5, 6, 7) |
| 40 | +
|
| 41 | +``` |
| 42 | +Then we print with the \* operator, where we will get the output as: |
| 43 | +``` |
| 44 | +1 2 4 5 6 7 |
| 45 | +``` |
| 46 | + |
| 47 | +Here the \* operator has unpacked the tuple, tuple1. |
| 48 | + |
| 49 | +Now that you have understood why \* is used, we can take a look at *args. *args is used in functions so that positional arguments are stored in the variable args. *args is just a naming convention, *anything can be used |
| 50 | +*args makes python functions flexible to handle dynamic arguments. |
| 51 | +```python |
| 52 | +def test1(*args): |
| 53 | + print(args) |
| 54 | + print(f"The number of elements in args = {len(args)}") |
| 55 | +a=list(range(0,10)) |
| 56 | +test1(*a) |
| 57 | +``` |
| 58 | +In the above snippet, we are sending a list of numbers to the test function which returns the following output: |
| 59 | +``` |
| 60 | +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
| 61 | +The number of elements in args = 10 |
| 62 | +``` |
| 63 | +If in the test1 we do not use \* in the argument |
| 64 | + |
| 65 | +```python |
| 66 | +def test1(*args): |
| 67 | + print(args) |
| 68 | + print(f"The number of elements in args = {len(args)}") |
| 69 | +a=list(range(0,10)) |
| 70 | +test1(a) |
| 71 | +``` |
| 72 | +we get the following result. This is a tuple containing a list. |
| 73 | +``` |
| 74 | +([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],) |
| 75 | +The number of elements in args = 1 |
| 76 | +``` |
| 77 | +## **kwargs |
| 78 | +**kwargs stands for keyword arguments. This is used for key and value pairs and similar to *args, this makes functions flexible enough to handle dynamic key value pairs in arguments. |
| 79 | +```python |
| 80 | +def test2(**kwargs): |
| 81 | + print(kwargs) |
| 82 | + print(f"The number of elements in kwargs = {len(kwargs)}") |
| 83 | +test2(a=1,b=2,c=3,d=4,e=5) |
| 84 | +``` |
| 85 | +The above snippet uses some key-value pairs and out test2 function gives the following output: |
| 86 | +``` |
| 87 | +{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} |
| 88 | +The number of elements in kwargs = 5 |
| 89 | +``` |
| 90 | +A dictionary with keys and values is obtained. |
| 91 | + |
| 92 | +## Decorators (@decorators) |
| 93 | +Now that we understand what first class object, *args, **kwargs is, we can move to decorators. |
0 commit comments