The functools module in Python delivers higher-order functions and operations on callable entities. It provides utilities for managing functions as first-class entities, facilitating function enhancement, adaptation, and elaboration without altering their underlying code. At first glance, it may appear straightforward, but it reveals powerful techniques to utilize your functions with greater efficiency. Whether you are developing a web application, crafting data manipulation scripts, or automating processes, functools can assist you in boosting performance and producing cleaner, more comprehensible code. In this blog, you will discover what the functools module encompasses.
Higher-order functions in Python can operate on or yield other functions. To apply such high-order functions in Python, the functools module can be employed. This module is a fundamental library in Python that presents tools making it simpler to manipulate/change/reuse functions in ways that typically would not be achievable with basic functions alone.
Why Should You Utilize functools in Python?
Utilizing functools is advisable for optimizing your code, reusing functions with preset arguments, caching costly computations, or altering functions without modifying their original format.
This makes your applications more productive, minimizes code redundancy, and allows you to work more intelligently, not just harder.
Importing functools in Python
Before you can implement any functions from the functools module, initial importation is necessary. Python simplifies this by readily incorporating the functools module.
Syntax:
import functools
Master Python and Enhance Your Tech Skills
Learn from industry experts and create real-world projects
Caching Results Using functools.lru_cache() in Python
Your functions may require considerable time to compute due to their complexity. In such instances, lru_cache assists in storing results to save time. Thus, if you invoke the same function again with identical inputs, you won’t have to wait anew.
Syntax:
@functools.lru_cache(maxsize=None) def function_name(parameters): # function body
Example:
Python
Code Copied!
var isMobile = window.innerWidth “);
editor95599.setValue(decodedContent); // Set the default text
editor95599.clearSelection();
editor95599.setOptions({
maxLines: Infinity
});
function decodeHTML95599(input) {
var doc = new DOMParser().parseFromString(input, “text/html”);
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard95599() {
“““javascript
const code = editor95599.getValue(); // Retrieve code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert(“Code successfully copied to clipboard!”);
data: {
language: “python”,
code: code,
cmd_line_args: “”,
variablenames: “”,
action: “compilerajax”
},
success: function(response) {
var myArray = response.split(“~”);
var data = myArray[1];
jQuery(“.output95599”).html(“
" + data + "");
jQuery(".maineditor95599 .code-editor-output").show();
jQuery("#runBtn95599 i.run-code").fadeOut();
}
});
}
function closeoutput95599() {
var code = editor95599.getSession().getValue();
jQuery(".maineditor95599 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn95599").addEventListener("click", copyCodeToClipboard95599);
document.getElementById("runBtn95599").addEventListener("click", runCode95599);
document.getElementById("closeoutputBtn95599").addEventListener("click", closeoutput95599);
Output:
Explanation: In this instance, the function executes a calculation to multiply numbers (8*8) and stores the outcome on the first invocation. During the second execution with the same parameters, it refrains from recalculation and retrieves the result from the cache.
Using functools.partial() to Fix Arguments in Python
There are instances when you frequently call a function with identical values for one or more arguments. You can utilize partial() to set those parameters in advance and create an efficient shortcut without redundancy.
editor91875.setValue(decodedContent); // Establish the default text
editor91875.clearSelection();
editor91875.setOptions({
maxLines: Infinity
});
function decodeHTML91875(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard91875() {
const code = editor91875.getValue(); // Retrieve code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert("Code successfully copied to clipboard!");
data: {
language: "python",
code: code,
cmd_line_args: "",
variablenames: "",
action: "compilerajax"
},
success: function(response) {
var myArray = response.split("~");
var data = myArray[1];
jQuery(".output91875").html("
" + data + "");
jQuery(".maineditor91875 .code-editor-output").show();
jQuery("#runBtn91875 i.run-code").fadeOut();
}
});
}
function closeoutput91875() {
var code = editor91875.getSession().getValue();
jQuery(".maineditor91875 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn91875").addEventListener("click", copyCodeToClipboard91875);
document.getElementById("runBtn91875").addEventListener("click", runCode91875);
document.getElementById("closeoutputBtn91875").addEventListener("click", closeoutput91875);
Output:
Explanation: In this example, we fixed the initial parameter x=3 employing partial(). Now find(7) operates like invoking multiply (3,7). It streamlines the code whenever a custom version of the existing function is desired.
Aggregating a Sequence Using functools.reduce() in Python
If you possess a list of numbers and wish to apply a function such as addition or multiplication to consolidate them
``````html
To consolidate items into a single value, reduce() can assist you with that. It operates by taking two elements at once and merging them, continuously.
Syntax:
functools.reduce(function, iterable)
Example:
Python
Code Copied!
var isMobile = window.innerWidth "");
editor38699.setValue(decodedContent); // Set the default text
editor38699.clearSelection();
editor38699.setOptions({
maxLines: Infinity
});
function decodeHTML38699(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
function copyCodeToClipboard38699() {
const code = editor38699.getValue(); // Get code from the editor
navigator.clipboard.writeText(code).then(() => {
jQuery(".maineditor38699 .copymessage").show();
setTimeout(function() {
jQuery(".maineditor38699 .copymessage").hide();
}, 2000);
}).catch(err => {
console.error("Error copying code: ", err);
});
}
function runCode38699() {
var code = editor38699.getSession().getValue();
jQuery("#runBtn38699 i.run-code").show();
jQuery(".output-tab").click();
jQuery.ajax({
url: "https://intellipaat.com/blog/wp-admin/admin-ajax.php",
type: "post",
data: {
language: "python",
code: code,
cmd_line_args: "",
variablenames: "",
action:"compilerajax"
},
success: function(response) {
var myArray = response.split("~");
var data = myArray[1];
function closeoutput38699() {
jQuery(".maineditor38699 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn38699").addEventListener("click", copyCodeToClipboard38699);
document.getElementById("runBtn38699").addEventListener("click", runCode38699);
document.getElementById("closeoutputBtn38699").addEventListener("click", closeoutput38699);
Output:
Explanation: In this instance, the reduce() function begins by summing 6 + 7 = 13, then 13 + 8 = 21, and ultimately 21 + 9 = 30.
Maintaining Metadata by Utilizing functools.wraps() in Python
It’s essential to retain the original function’s name and documentation when you opt to create decorators. Decorators are functions that alter other functions. Without applying wraps, significant data like the name and docstring may be lost.
Syntax:
@functools.wraps(original_function) def wrapper_function(arguments): # function body
Example:
Python
Code Copied!
var isMobile = window.innerWidth "");
editor48988.setValue(decodedContent); // Set the default text
editor48988.clearSelection();
editor48988.setOptions({
maxLines: Infinity
});
function decodeHTML48988(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
function copyCodeToClipboard48988() {
const code = editor48988.getValue(); // Get code from the editor
navigator.clipboard.writeText(code).then(() => {
jQuery(".maineditor48988 .copymessage").show();
setTimeout(function() {
jQuery(".maineditor48988 .copymessage").hide();
}, 2000);
}).catch(err => {
console.error("Error copying code: ", err);
});
}
``````javascript
2000);
}).catch(err => {
console.error("Issue encountered while copying code: ", err);
});
}
data: {
language: "python",
code: code,
cmd_line_args: "",
variablenames: "",
action:"compilerajax"
},
success: function(response) {
var myArray = response.split("~");
var data = myArray[1];
jQuery(".output48988").html("
"+data+"");
jQuery(".maineditor48988 .code-editor-output").show();
jQuery("#runBtn48988 i.run-code").hide();
}
})
}
function dismissOutput48988() {
var code = editor48988.getSession().getValue();
jQuery(".maineditor48988 .code-editor-output").hide();
}
// Add event listeners to the buttons
document.getElementById("copyBtn48988").addEventListener("click", copyCodeToClipboard48988);
document.getElementById("runBtn48988").addEventListener("click", executeCode48988);
document.getElementById("closeoutputBtn48988").addEventListener("click", dismissOutput48988);
Result:
Clarification: In this instance, the initial function name greet and its docstring “Says hello.” remain intact even after being decorated. This outcome stems directly from the utilization of @functools.wraps(func). Furthermore, a decorator envelops another function, and that @wraps aids in preserving the identity of the encapsulated function.
Comparison Table: Primary Methods of functools in Python
Method
Description
Syntax
Common Use
lru_cache()
Stores the outcomes of function executions to prevent recalculation, enhancing the speed of your code.
@functools.lru_cache(maxsize=None)
Accelerating repeated function executions through result caching.
partial()
Generates a new function with certain arguments pre-fixed.
functools.partial(func, fixed_args)
Simplifying elaborate function calls with predetermined arguments.
reduce()
Consolidates an iterable into a single cumulative value by applying a function together.
functools.reduce(function, iterable)
Combining a list into one result, such as sum or product.
wraps()
Maintains the metadata of the original function when decorators are employed.
@functools.wraps(func)
Preserving the original function’s name, docstring, and signature after decoration.
Facilitating Function Overloading with functools.singledispatch
If you require a situation where one single function behaves differently based on the type of argument it receives, you typically have to write numerous if-else statements. You can try to overload a function elegantly, without cluttering your code, through functools.singledispatch.
Syntax:
@functools.singledispatch def function_name(arg): # default behavior @function_name.register(type) def function_name_for_type(arg): # behavior for the specific type
Illustration:
Python
Code Copied!
var isMobile = window.innerWidth “);
editor37844.setValue(decodedContent); // Set the default text
editor37844.clearSelection();
editor37844.setOptions({
maxLines: Infinity
});
function decodeHTML37844(input) {
var doc = new DOMParser().parseFromString(input, “text/html”);
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard37844() {
const code = editor37844.getValue(); // Get code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert(“Code copied to clipboard!”);
data: {
language: “python”,
code: code,
cmd_line_args: “”,
variablenames: “”,
action:”compilerajax”
},
success: function(response) {
var myArray = response.split(“~”);
var data = myArray[1];
jQuery(“.output37844”).html(“
"+data+"");
jQuery(".maineditor37844 .code-editor-output").show();
jQuery("#runBtn37844 i.run-code").hide();
``````html
i.run-code").hide();
}
})
}
function closeoutput37844() {
var code = editor37844.getSession().getValue();
jQuery(".maineditor37844 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn37844").addEventListener("click", copyCodeToClipboard37844);
document.getElementById("runBtn37844").addEventListener("click", runCode37844);
document.getElementById("closeoutputBtn37844").addEventListener("click", closeoutput37844);
Output:
Clarification: In this scenario, you defined a function referred to as greet. This function operates differently based on whether you provide a string or an integer. This feature enables your application to intelligently adapt according to the type of input received.
Applications for functools in Python
Application 1: Streamlining rich comparisons in classes via functools.total_ordering
When creating custom classes, it's frequently necessary to establish multiple comparison methods such as <, <=, >, >=. Manually coding all of them can be quite tedious. functools.total_ordering addresses this by enabling you to define only one or two methods, which it will then use to generate the additional comparisons for you. This significantly reduces the time spent on classes that require comprehensive comparison capabilities.
Structure:
@functools.total_ordering class ClassName: def __eq__( self , other): # Define the equality logic def __lt__( self , other): # Define the less-than logic
Illustration:
Python
Code Copied!
var isMobile = window.innerWidth ");
editor76503.setValue(decodedContent); // Set the default text
editor76503.clearSelection();
editor76503.setOptions({
maxLines: Infinity
});
function decodeHTML76503(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard76503() {
const code = editor76503.getValue(); // Retrieve code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert("Code copied to clipboard!");
data: {
language: "python",
code: code,
cmd_line_args: "",
variablenames: "",
action:"compilerajax"
},
success: function(response) {
var myArray = response.split("~");
var data = myArray[1];
jQuery(".output76503").html("
"+data+"");
jQuery(".maineditor76503 .code-editor-output").show();
jQuery("#runBtn76503 i.run-code").hide();
}
})
}
function closeoutput76503() {
var code = editor76503.getSession().getValue();
jQuery(".maineditor76503 .code-editor-output").hide();
}
// Bind event listeners to the buttons
document.getElementById("copyBtn76503").addEventListener("click", copyCodeToClipboard76503);
document.getElementById("runBtn76503").addEventListener("click", runCode76503);
document.getElementById("closeoutputBtn76503").addEventListener("click", closeoutput76503);
Output:
Clarification: In this instance, the @functools.total_ordering decorator automatically generates the missing comparison methods (le, gt, and ge) based on the methods you define (eq and lt), which allows you to utilize all comparison operators without the need to implement them manually.
Application 2: Easy way to cache indefinitely
Structure:
@functools.cache def function_name(parameters): # body of function
Illustration:
Python
Code Copied!
``````html
var isMobile = window.innerWidth ");
editor64121.setValue(decodedContent); // Establish the default text
editor64121.clearSelection();
editor64121.setOptions({
maxLines: Infinity
});
function decodeHTML64121(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard64121() {
const code = editor64121.getValue(); // Retrieve code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert("Code copied to clipboard!");
function closeoutput64121() {
var code = editor64121.getSession().getValue();
jQuery(".maineditor64121 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn64121").addEventListener("click", copyCodeToClipboard64121);
document.getElementById("runBtn64121").addEventListener("click", runCode64121);
document.getElementById("closeoutputBtn64121").addEventListener("click", closeoutput64121);
Output:
Explanation: In this instance, the first invocation calculates 12*11, but the subsequent call doesn't; it fetches the result from the cache. functools.cache simplifies things more than lru_cache when you don't mind memory limitations and prefer maximum ease.
Optimal Strategies for Utilizing functools in Python
Adhere to these straightforward suggestions to enhance your experience with functools:
Always utilize @wraps when developing decorators to maintain the original function’s name and documentation.
Employ lru_cache() solely when your function relies entirely on its inputs and possesses no external side effects.
Consistently set a sensible maxsize when caching to prevent memory overflow.
Choose partial to simplify APIs and avoid the necessity of manually writing repetitive wrapper functions.
Utilize reduce only when essential; at times, a loop can be more comprehensible for newcomers.
Complimentary Python Course for Beginners
Code at your own rhythm and create tangible projects
A module that enhances your code’s intelligence, accelerates execution, and simplifies usability is one of the characteristics that make functools one of the most valuable modules in Python programming. Whether you are implementing caching for performance enhancement, applying partial for easier function calls, using reduce to condense sequences, or applying wraps to retain metadata; the functools module has an extensive array of helpful tools. Incorporating this module can conserve your time, enhance your overall code architecture, and unlock potential you may not even recognize.
To elevate your skills, enroll in our Python training course and gain practical experience. Additionally, prepare for job interviews with our Python interview questions, crafted by industry specialists.
Frequently Asked Questions on functools in Python
Q1. Is functools a built-in module in Python?
Yes, it is included in Python’s standard library, and no external installation is required.
Q2. When is it advisable to use lru_cache?
Employ it when you possess a function whose output relies solely on its input and is invoked numerous times with identical arguments.
Q3. Is it possible to limit the number of results stored by lru_cache?
Indeed, you can define a maxsize parameter like @lru_cache(maxsize=100).
“““html
Q4. Why utilize functools.partial()?
Employ it when you wish to formulate a version of a function with reduced parameters for more convenient usage.
Q5. What occurs if I don’t implement wraps in a decorator?
If you don’t implement wraps, the wrapped function forfeits its original name, docstring, and metadata, complicating debugging.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.