Higher-Order Functions — Python
A programming language is said to support First Class Functions if it treats functions as first-class objects. By definition, a “first-class object” in a program entity is an object that can be passed around just like other objects. It has the following characteristics:
- can have properties and methods.
- can be assigned to a variable.
- can be passed as an argument to a function.
- can be returned as a result of another function.
Let’s try to understand each property through code.
- Properties and Methods
Each Method/Function you create in Python has a set of default properties and methods, which can inspect using the dir()
method. In the below example, I have defined a hello_world function that prints the string Hello World!
.
def hello_world():
print("Hello World!")
When we call the dir()
function on the hello_world method, we could see all the default methods that are part of it.
print(dir(hello_world))
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
You can call any of these methods tied with the function. For example:
hello_world.__name__
# 'hello_world'
You can also use type
to understand that the function we create is an instance of the function class.
print(type(hello_world))
# <class 'function'>
2. Assigning Function to Variables
We can also assign functions to variables.
def hello_world_function(name):
print("Hello " + name + "!")hello_world_variable = hello_world_function
Here we are assigning hello_world_function
function to the variable hello_world_variable
. Now hello_world_variable
is a functions object which means, we can call it just like the hello_world_function
.
hello_world_variable("Tharun")
# Hello Tharun!
This assignment does not call the function instead it takes the function object referenced by hello_world_function
and creates a second name pointing to it.
hello_world_function
# <function hello at 0x0000020127C982F0>hello_world_variable
# <function hello at 0x0000020127C982F0>
3. Function as an Argument
Since Function is an object, you can pass it as an argument much similar to a variable.
Let’s consider iterating over a list of items and printing them sequentially. We can easily build an iterate
function.
def iterate(items):
for item in items:
print(item)
This is usual stuff. What if we want to do something different from printing the items? That’s where Higher-Order Functions come in. We can create a function iterate_custom
that takes in both the item list and the function that needs to be applied to each item.
def iterate_custom(items, function):
for item in items:
function(item)
By doing this, we have created a function that can do anything with the list that involves sequential iteration. This is a higher level of abstraction and this also makes our code reusable.
4. Return Function from Function
This is usually done to have a wrapper function that decides the control flow or to decide which function should be called. For example:
def square(num):
return num * numdef cube(num):
return square(num) * numdef power_of_num(power):
if power == 2:
return square
elif power == 3:
return cubenum_powers = power_of_num(2)
# num_powers is assigned with the square methodnum_powers(5)
# 25
We have defined methods square
and cube
which are pretty usual. The third method power_of_num
is a wrapper function that returns either of the first two methods based on the variable value. In this case, power_of_num
is called with the variable value 2
. Square
method would be returned now and assigned in the variable num_powers
. Now, if we call the num_powers
variable, it would act as the square
method.
num_powers = power_of_num(3)
# num_powers is assigned with the cube methodnum_powers(5)
# 125
Got questions? Feel free to comment here.
If you liked this article, click the 👏 so other people will see it here on Medium.