This article is focused at making you understand the property of functions to behave as first class objects. We will cover the following:
You might have heard of the famous saying, "In Python, everything is an object". Very confusing as it may sound, this is absolutely true. In Python, every single entity is represented as an object ( Yes, object from the OOP. In case you don't know about OOP, I have got it briefly covered in this article ). This concept has given rise to many methodologies and principles in Python like Closures and Decorators.
Psst.. If you are in a hurry, you can watch the video version of this post instead
Alright, let's get started.
- Appear in an expression
- Be assigned to a variable
- Be used as an argument
- Be returned by a function call
So, what do you think would be candidates to this? Well, Python datatypes fit these criteria, so datatypes like Integer, String, Boolean etc are first-class objects. So, let me ask: Are loops and conditionals first-class objects? Of course not since they both are failing multiple criteria. Finally, we can achieve all the aforementioned with functions as well! Therefore, functions are also first-class objects.
Given below is a function which increments a number by 1:
def plusOne(number): return number+1
Now to prove that functions can be treated as other objects, let me go ahead and rename this function like so:
def plusOne(number): return number+1 #renaming the above function re = plusOne #calling both the functions plusOne(10) # 11 re(10) # 11
You'd notice that both of them gives you the same output. Do you remember encountering this behavior elsewhere? Well, if you run the following code, you might get an idea:
x = 11 y = x print(x) # 11 print(y) # 11
Surprising ain't it? Therefore, functions behave like the first-class objects. This is something unique that other programming languages like C, C++ never had. Functions in Python can be treated as first class objects (String, Integer, etc).
Now, I am going to spice things up. This might seem a bit weird in the beginning but you will understand it and grasp the concept pretty quick.
If you remember that we can store the First Class Objects in some other data structure like Lists, Dictionaries right? Well, this means that a function too can be stored in these data structures and used accordingly. Let me explain this more briefly (using List as the data structure):
def plusOne(number): return number+1 def plusTwo(number): return number+2 def plusThree(number): return number+3 def plusFour(number): return number+4 # list storing function objects func_list = [plusOne, plusTwo, plusThree, plusFour] # executing each function for func in func_list: print(func(10)) # It will print out ---> 11, 12, 13, 14
In the above snippet, I have created a
func_list list which will store the function objects. Now, before I move further, it is imperative to understand that Python does not make a call to the function unless you succeed it with brackets
(). So, if I only do this:
print(plusOne) # prints out ---> <function plusOne at 0x000001B4FC7FEF70>
Python would only give me the function reference as shown above. Alright, let's go back. Now, the
func_list holds the function objects (which are not yet executed). Then, I ran a for loop, accessed each function and then finally executed it with the help of parenthesis and a parameter, 10.
Great stuff! I believe now you got to know what the original behavior of functions are. To truly solidify your grasp on this concept, try to make use of it wherever you find its possible use case.
Let me try and come up with a use case of first class functions:
def plusOne(number): return number+1 def plusTwo(number): return number+2 def listModifier(li, func): result =  for element in li: result.append(func(element)) return result # executing listModifier print(listModifier([1,2,3,4], plusOne)) # prints out ---> [2,3,4,5]
In the above snippet, I passed a function (
plusOne) as the parameter to another function (
listModifier). Then, I made a call to
plusOne from within the
listModifier function. This would trigger the
plusOne function and will increment each value of list passed and then append it to a
result list. Finally, after the above operation, simply returned
Now, let's suppose for some reason, the client comes to me and tells me that instead of incrementing each value of the element by 1, do it by 2, all I would have to do is simply replace the
plusOne parameter of
plusTwo like so:
print(listModifier([1,2,3,4], plusTwo)) # pretty neat eh? # prints out ---> [3,4,5,6]
Let me tell you that, you have reached a major milestone by learning this concept. First Class Function form the basis of several other design patterns and concepts such as Closures and Decorators. You'd have a better understanding of those topics by having a knowledge of first class functions beforehand.
If you want to support me and my contents, then go ahead and consider doing it. I would highly appreciate that: