Prerequisites
In order to learn about high order functions in Python, we must have basic knowledge of the following concepts:
- Python functions
- Parameters
- Python objects
- Python decorators
To begin, let's focus on the initial topic: higher-order functions, and gain a fundamental understanding of them.
High Order Functions
A function that accepts another function as an argument or one that produces another function as its output is referred to as a Higher-Order Function. Higher-Order Functions interact with other functions defined within the program.
An important characteristic of higher-order functions is their capacity to accept both functions and methods as parameters or to yield functions as their output. In Python, this notion of higher-order functions is integrated into every facet of the language.
Properties of High order functions
Now, we will discuss some of the important properties of high order functions that are applicable in Python as well.
- In high order function, we can store a function inside a variable.
- In high order function, a function can act as an instant of an object type.
- In high order function, we can return a function as a result of another function.
- In high order function, we can pass a function as a parameter or argument inside another function.
- We can store Python high order functions in data structures format such as lists, hash tables, etc.
Different Ways to Define High Order Function
Following are the ways to define High order functions in a Python code that we are going to discuss in this tutorial.
- Using functions as objects in High order function
- Returning function as a result in high order function
- Functions as a parameter for another function
- Decorators as high order function
At this point, we will delve into a thorough examination of the methods mentioned earlier and explore their execution as higher-order functions within a Python program.
Method 1: Using functions as objects in High order function
In Python, it is also possible to assign a function to a variable. This assignment does not invoke the function itself; rather, it establishes a reference to the defined function. Consequently, this practice of assigning a function to a variable creates a higher-order function within the program.
Examine the subsequent example program to understand the execution of the method we previously covered:
Example:
# a default function to take another function parameter
def spell(text):
# Making text in upper
return text.upper()
# Taking text as user input
text = input("Enter a text to print it in uppercase and double: ")
# Spell function with text
print(spell(text))
# Assigning variable with the default function
scream = spell
# Scream with text variable
print(scream(text))
Output:
Enter a text to print it in uppercase and double: C# Tutorial
Example
Example
Method 2: Functions as a parameter for another function
In essence, Python functions are treated as objects within the language. This characteristic allows us to utilize Python functions as arguments in other functions, thereby enabling the creation of higher-order functions within our programs.
Examine the subsequent program to grasp the execution of the previously mentioned method:
Example:
# Default function for making text uppercase
def scream(word):
return word.upper()
# Default function for making text lowercase
def spell(word):
return word.lower()
# A third function that work as a high order function
def speak(funct):
# Storing the function in a variable in high order function
speaking = funct("Hello Python Developers! You are welcomed to C# Tutorial")
print(speaking)
# Printing text in uppercase
speak(scream)
# Printing text in lowercase
speak(spell)
Output:
HELLO PYTHON DEVELOPERS! YOU ARE WELCOMED TO C# Tutorial
hello python developers! you are welcomed to logicpractice
Method 3: Returning function as a result in high order function
It is also possible for a function to yield another function as its return value, thereby classifying the original function as a higher-order function.
Examine the subsequent example program to understand the application of the method we previously covered:
Example:
# A default function for addition
def Adding(a):
# Nested function with second number
def Addition(b):
return a + b # addition of two numbers
return Addition # Result
# Taking both number variable as user input
a = int(input("Enter First Number: "))
b = int(input("Enter Second Number: "))
# Assigning nested adding function to a variable
AddVariable = Adding(a)
# Using variable as high order function
Result = AddVariable(b)
# Printing result
print("Sum of Two numbers given by you is: ", Result)
Output:
Enter First Number: 24
Enter Second Number: 26
Sum of Two numbers given by you is: 50
Method 4: Decorators as high order function
In Python, decorators serve as a prominent example of higher-order functions. They enable us to alter the behavior of the functions or methods defined within our program. Furthermore, decorators facilitate the encapsulation of one function within another, thereby enhancing the functionality of the inner or parent function. Remarkably, it is possible to encapsulate a function within another without making any permanent changes to the original parent function.
In Python, decorators are a design pattern in which a function is passed as an argument to another function. Subsequently, these decorators are invoked within the function that they are meant to enhance. Below is an illustrative example of the syntax utilized for defining a decorator in a Python script.
Syntax
# Using a decorator
@JTP_Decorator
def Python_Decorator():
.
.
The syntax for the decorator mentioned above corresponds to the following Python implementation of a higher-order function.
# Using Python default function as Python decorators
def Python_Decorator():
.
.
Python_Decorator = @JTP_Decorator(Python_Decorator)
In the code provided above, we have utilized @JTPDecorator as a callable function within the default PythonDecorator function. To achieve the desired output of the wrapper function, we simply need to incorporate a few additional lines of code into this framework.
Examine the subsequent program to gain insight into the execution of the previously mentioned method:
Example:
# Using default function as Python decorators
def Python_Decorator(funct):
# Inner nested function
def inner():
print("This line of code will be printed before the execution of high order function")
funct()
print("This line of code will be printed after the execution of high order function")
return inner
# A default function as decorator
def JTP_Decorator():
print("This line of code will be printed inside the execution of high order function")
JTP_Decorator = Python_Decorator(JTP_Decorator) # Python decorator as high order function
# Python decorator calling out as high order function
JTP_Decorator()
Output:
This line of code will be printed before the execution of high order function
This line of code will be printed inside the execution of high order function
This line of code will be printed after the execution of high order function