Python Functions - First Class Citizens/Objects
You might have already heard that everything is an object in Python, even classes and functions. Yes, you heard right. All data in Python is represented by objects or relationships between the objects. Things like integer, string, boolean, classes, functions, etc. are all objects in Python. In any programming language, functions are said to be first-class functions (or objects) if language treats functions as first-class citizens.
Functions in Python are called first-class citizens/objects as they support all the operations and are manipulated similar to other kinds of objects (integer, boolean, string, etc). For example, a function can be passed as an argument to other functions, can be assigned as a value to a variable, can be stored in data structures, and can be returned by another function.
Assigning a Function to a Variable
In Python, it is possible to assign a function to a variable and perform operations on that like other objects.
def add(a, b): return a + b sum = add(2, 3) print(sum)
In the above code, the function add returns the sum of two numbers and assigns to a variable named sum, this is a very common approach followed by programmers in any programming language. Here is another form of the code:
def add(a, b): return a + b sum = add print(sum) res = sum(2, 5) print(res)
<function add at 0x10b42ab00> 7
In the above code, the add function is assigned to a variable sum without executing it. Using a function without parentheses () will not execute it. The value stored inside the sum is a function, so we can use that variable to perform different things. In the next line, the variable sum is used to call the function (add) stored in it and this time it returns the sum of numbers.
Passing Function to Another Function
Since functions are first-class citizens in Python, we can pass them to other functions as arguments. Let us continue with the same code example from above (with some additional):
def add(a, b): return a + b def multi(a, b): return a*b def print_result(a, b, my_func): return my_func(a, b) sum = print_result(5, 6, add) print(sum) mul = print_result(5, 6, multi) print(mul)
The third argument of the function print_result is expected to be a function type object and, add and multi functions are passed as arguments while calling it.
Returning a Function from Another Function
This one is a very powerful key concept of functional programming. In Python, we can return a function because functions are treated like any other object.
def print_message(my_msg): def message(): print(my_msg) return message msg = print_message("Hello there!") msg()
Here outer function print_message() takes a variable as an argument and assigns returned inner function message() to msg variable. Variable my_msg lasts inside the message() function when it is called. So, finally when the msg() is executed then it prints out the message passed as the argument to the print_message(). Retaining behaviors of outer function inside the inner functions (even after the scope of the outer function has lasted past the execution) is a powerful concept and supported in many programming languages. We know this concept as closures. Using this concept, Python keeps the scope of my_msg inside the inner function.
Wrap up Time :
- Everything is an object in Python that includes functions too. We can assign functions to variables, passed as an argument to another function, return a function from another function, and can store them in data structures.
- We can nest functions in Python and an inner function can capture and carry some behavior of an outer function. This concept is called closures in computer programming.