functools
module provides functions that act on other functions and returns modified functions. It lets us add more functionality by providing a wrapper around existing functions.
We'll be covering this tutorial in 2 parts. In this part, we'll be covering functions of this module and in 2nd part, we'll be covering annotations available for the same functionalities.
import functools
import datetime
import pytz
import time
functools.cmp_to_key(func)
- It converts old-style comparison function to key function.Comparison function takes 2 arguments and returns negative, zero and positive numbers based on less than, equal and greater than the relationship between 2 elements. The key function takes single element and returns a value that will then be used for sorting.
class Employee(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name + ' : , Age : '+str(self.age)
e1 = Employee('Sunny',27)
e2 = Employee('Sumit',27)
e3 = Employee('Anup',35)
e4 = Employee('Ashwin',35)
e5 = Employee('Rohit',38)
e6 = Employee('Irfan',38)
e7 = Employee('Ethesh',22)
e8 = Employee('Kaushal',45)
def emp_cmp(emp1,emp2):
return 1 if emp1.age > emp2.age else -1 if emp1.age < emp2.age else 0
sorted_employees = sorted([e8,e7,e6,e5,e4,e3,e2,e1], key = functools.cmp_to_key(emp_cmp))
print([str(emp) for emp in sorted_employees]) ## Please make a not that it's stable sort as it maintained same order for employees with same age.
functools.partial(func,*args,**kwargs)
- It wraps function provided to it with arguments provided as args & kwargs set and returns partial object
. It's generally used to freeze few arguments of some function with too many arguments so that one can avoid giving the same arguments again and again.functools.partialmethod(func,*args,**kwargs)
- It returns a new partialmethod descriptor
which is the same as partial object
. It's designed to be method definition in class than directly being called partial
. It freezes all parameters.freezed_params = {'hour':5,'minute':0,'second':59,'microsecond':999}
partial_datetime = functools.partial(datetime.datetime, **freezed_params)
partial_datetime(2015,1,1), partial_datetime(2018,2,21), partial_datetime(2017,1,31)
partial_datetime.func, partial_datetime.args, partial_datetime.keywords
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def decrease_salary(self, percentage):
self.salary -= (self.salary*(percentage/100))
def increase_salary(self, percentage):
self.salary += (self.salary*(percentage/100))
highest_performar_increase = functools.partialmethod(increase_salary, 30)
average_performar_increase = functools.partialmethod(increase_salary, 15)
bad_performar_decrease = functools.partialmethod(decrease_salary, 5)
e1 = Employee('Sumit', 25000)
e2 = Employee('Jayesh', 35000)
e3 = Employee('Rohit', 35000)
e1.highest_performar_increase(), e2.average_performar_increase(), e3.bad_performar_decrease()
e1.salary, e2.salary, e3.salary
functools.reduce(function,iterable[,initializer])
- It applies function
of 2 arguments cummunlatively to all elements of iterable
from left to right to return single value.If initializer
is provided then function is performed first on initializer
and first element of iterable
.print(functools.reduce(lambda x,y : x - y, range(1,5))) # (((1-2)-3)-4)
print(functools.reduce(lambda x,y : x - y, range(1,5), 100 )) # ((((100-1)-2)-3)-4)
functools.update_wrapper(wrapper, wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES)
- It assigns/updates atrributes of wrapped(original function)
to wrapper
function.functools.WRAPPER_ASSIGNMENTS, functools.WRAPPER_UPDATES
def outer(func):
def inner(*args):
print('Before execution')
func(*args)
print('After execution')
return inner
def print_title(title):
"""
Simple print functionality
"""
print(title)
wrapper = outer(print_title)
print('Attributes before update : '+ str(dict(zip(['__module__', '__name__', '__qualname__', '__doc__', '__annotations__','__dict__'],
[wrapper.__module__,wrapper.__name__, wrapper.__qualname__, wrapper.__doc__, wrapper.__annotations__, wrapper.__dict__]))))
functools.update_wrapper(wrapper, print_title)
print('\nAttributes after update : '+ str(dict(zip(['__module__', '__name__', '__qualname__', '__doc__', '__annotations__','__dict__'],
[wrapper.__module__,wrapper.__name__,wrapper.__qualname__, wrapper.__doc__, wrapper.__annotations__, wrapper.__dict__]))))
If you are more comfortable learning through video tutorials then we would recommend that you subscribe to our YouTube channel.
When going through coding examples, it's quite common to have doubts and errors.
If you have doubts about some code examples or are stuck somewhere when trying our code, send us an email at coderzcolumn07@gmail.com. We'll help you or point you in the direction where you can find a solution to your problem.
You can even send us a mail if you are trying something new and need guidance regarding coding. We'll try to respond as soon as possible.
If you want to