Functools module in Python

26 Mar, 2020
Functools module is for higher-order functions that work on other functions. It provides functions for working with other functions and callable objects to use or extend them without completely rewriting them. This module has two classes – partial and partialmethod.
A partial function is an original function for particular argument values. They can be created in Python by using “partial” from the functools library. The __name__ and __doc__ attributes are to be created by the programmer as they are not created automatically. Objects created by partial() have three read-only attributes:
Syntax:
partial(func[, *args][, **keywords])
partial.func – It returns the name of parent function along with hexadecimal address.
partial.args – It returns the positional arguments provided in partial function.
partial.keywords – It returns the keyword arguments provided in partial function.
Example:
from functools import partial    def power(a, b):    return a**b  # partial functionspow2 = partial(power, b = 2)pow4 = partial(power, b = 4)power_of_5 = partial(power, 5)  print(power(2, 3))print(pow2(4))print(pow4(3))print(power_of_5(2))  print('Function used in partial function pow2 :', pow2.func)print('Default keywords for pow2 :', pow2.keywords)print('Default arguments for power_of_5 :', power_of_5.args)
Output :
8168125Function used in partial function pow2 : <function power at 0x000001CCBBE8C7B8>Default keywords for pow2 : {‘b’: 2}Default arguments for power_of_5 : (5, )
It is a method definition of an already defined function for specific arguments like a partial function. However, it is not callable but is only a method descriptor. It returns a new partialmethod descriptor.
Syntax:
partialmethod(func, *args, **keywords)
Example:
from functools import partialmethod    class Demo:    def __init__(self):        self.color = 'black'    def _color(self, type):        self.color = type      set_red = partialmethod(_color, type ='red')    set_blue = partialmethod(_color, type ='blue')    set_green = partialmethod(_color, type ='green')    obj = Demo()print(obj.color)obj.set_blue()print(obj.color)
Output :
black
blue

Cmp_to_keyIt converts a comparison function into a key function. The comparison function must return 1, -1 and 0 for different conditions. It can be used in key functions such as sorted(), min(), max().Syntax :function(iterable, key=cmp_to_key(cmp_function)) Example:from functools import cmp_to_key  # function to sort according to last characterdef cmp_fun(a, b):    if a[-1] > b[-1]:        return 1    elif a[-1] < b[-1]:        return -1    else:        return 0  list1 = ['geeks', 'for', 'geeks']l = sorted(list1, key = cmp_to_key(cmp_fun))print('sorted list :', l)Output :sorted list : ['for', 'geeks', 'geeks']

It converts a comparison function into a key function. The comparison function must return 1, -1 and 0 for different conditions. It can be used in key functions such as sorted(), min(), max().
Syntax :
function(iterable, key=cmp_to_key(cmp_function)) 
Example:
from functools import cmp_to_key  # function to sort according to last characterdef cmp_fun(a, b):    if a[-1] > b[-1]:        return 1    elif a[-1] < b[-1]:        return -1    else:        return 0  list1 = ['geeks', 'for', 'geeks']l = sorted(list1, key = cmp_to_key(cmp_fun))print('sorted list :', l)
Output :
sorted list : ['for', 'geeks', 'geeks']

ReduceIt applies a function of two arguments repeatedly on the elements of a sequence so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x^y, [1, 2, 3, 4]) calculates (((1^2)^3)^4). If the initial is present, it is placed first in the calculation, and if the default result when the sequence is empty.Syntax :reduce(function, sequence[, initial]) -> value  Example:from functools import reducelist1 = [2, 4, 7, 9, 1, 3]sum_of_list1 = reduce(lambda a, b:a + b, list1)  list2 = ["abc", "xyz", "def"]max_of_list2 = reduce(lambda a, b:a if a>b else b, list2)  print('Sum of list1 :', sum_of_list1)print('Maximum of list2 :', max_of_list2)Output :Sum of list1 : 26
Maximum of list2 : xyz

It applies a function of two arguments repeatedly on the elements of a sequence so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x^y, [1, 2, 3, 4]) calculates (((1^2)^3)^4). If the initial is present, it is placed first in the calculation, and if the default result when the sequence is empty.Syntax :
reduce(function, sequence[, initial]) -> value  
Example:
from functools import reducelist1 = [2, 4, 7, 9, 1, 3]sum_of_list1 = reduce(lambda a, b:a + b, list1)  list2 = ["abc", "xyz", "def"]max_of_list2 = reduce(lambda a, b:a if a>b else b, list2)  print('Sum of list1 :', sum_of_list1)print('Maximum of list2 :', max_of_list2)
Output :
Sum of list1 : 26
Maximum of list2 : xyz

Total_orderingIt is a class decorator that fills in the missing comparison methods (__lt__, __gt__, __eq__, __le__, __ge__). If a class is given which defines one or more comparison methods, “@total_ordering” automatically supplies the rest as per the given definitions. However, the class must define one of __lt__(), __le__(), __gt__(), or __ge__() and additionally, the class should supply an __eq__() method.Example:from functools import total_ordering  @total_orderingclass N:    def __init__(self, value):        self.value = value    def __eq__(self, other):        return self.value == other.value      # Reverse the function of     # '<' operator and accordingly    # other rich comparison operators    # due to total_ordering decorator    def __lt__(self, other):        return self.value > other.value    print('6 > 2 :', N(6)>N(2))print('3 < 1 :', N(3)<N(1))print('2 <= 7 :', N(2)<= N(7))print('9 >= 10 :', N(9)>= N(10))print('5 == 5 :', N(5)== N(5))Output :6 > 2 : False
3 < 1 : True
2 = 10 : True
5 == 5 : True

Example:
from functools import total_ordering  @total_orderingclass N:    def __init__(self, value):        self.value = value    def __eq__(self, other):        return self.value == other.value      # Reverse the function of     # '<' operator and accordingly    # other rich comparison operators    # due to total_ordering decorator    def __lt__(self, other):        return self.value > other.value    print('6 > 2 :', N(6)>N(2))print('3 < 1 :', N(3)<N(1))print('2 <= 7 :', N(2)<= N(7))print('9 >= 10 :', N(9)>= N(10))print('5 == 5 :', N(5)== N(5))
Output :
6 > 2 : False
3 < 1 : True
2 = 10 : True
5 == 5 : True

Update_wrapperIt updates a wrapper function to look like the wrapped function. For example, in case of partial functions, we can update partial function to look like its parent function by using update_wrapper(partial, parent). This will update the documentation(__doc__) and name(__name__) of the partial function to same as of the parent function.Syntax :update_wrapper(wrapper, wrapped[, assigned][, updated])Example:from functools import update_wrapper, partial  def power(a, b):    ''' a to the power b'''    return a**b  # partial functionpow2 = partial(power, b = 2)pow2.__doc__='''a to the power 2'''pow2.__name__ = 'pow2'  print('Before wrapper update -')print('Documentation of pow2 :', pow2.__doc__)print('Name of pow2 :', pow2.__name__)print()update_wrapper(pow2, power)print('After wrapper update -')print('Documentation of pow2 :', pow2.__doc__)print('Name of pow2 :', pow2.__name__)Output :Before wrapper update -
Documentation of pow2 : a to the power 2
Name of pow2 : pow2

After wrapper update -
Documentation of pow2 :  a to the power b
Name of pow2 : power

It updates a wrapper function to look like the wrapped function. For example, in case of partial functions, we can update partial function to look like its parent function by using update_wrapper(partial, parent). This will update the documentation(__doc__) and name(__name__) of the partial function to same as of the parent function.
Syntax :
update_wrapper(wrapper, wrapped[, assigned][, updated])
Example:
from functools import update_wrapper, partial  def power(a, b):    ''' a to the power b'''    return a**b  # partial functionpow2 = partial(power, b = 2)pow2.__doc__='''a to the power 2'''pow2.__name__ = 'pow2'  print('Before wrapper update -')print('Documentation of pow2 :', pow2.__doc__)print('Name of pow2 :', pow2.__name__)print()update_wrapper(pow2, power)print('After wrapper update -')print('Documentation of pow2 :', pow2.__doc__)print('Name of pow2 :', pow2.__name__)
Output :
Before wrapper update -
Documentation of pow2 : a to the power 2
Name of pow2 : pow2

After wrapper update -
Documentation of pow2 :  a to the power b
Name of pow2 : power

WrapsIt is a function decorator which applies update_wrapper() to the decorated function. It is equivalent to partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated).Example:from functools import wraps  def decorator(f):    @wraps(f)    def decorated(*args, **kwargs):        """Decorator's docstring"""        return f(*args, **kwargs)      print('Documentation of decorated :', decorated.__doc__)    return decorated  @decoratordef f(x):    """f's Docstring"""    return x  print('f name :', f.__name__)print('Documentation of f :', f.__doc__)Output :Documentation of decorated : f's Docstring
f name : f
Documentation of f : f's Docstring

Example:
from functools import wraps  def decorator(f):    @wraps(f)    def decorated(*args, **kwargs):        """Decorator's docstring"""        return f(*args, **kwargs)      print('Documentation of decorated :', decorated.__doc__)    return decorated  @decoratordef f(x):    """f's Docstring"""    return x  print('f name :', f.__name__)print('Documentation of f :', f.__doc__)
Output :
Documentation of decorated : f's Docstring
f name : f
Documentation of f : f's Docstring

LRU_cacheLRU_cache is a function decorator used for saving up to the maxsize most recent calls of a function. This can save time and memory in case of repeated calls with the same arguments.If *maxsize* is set to None, the cache can grow without bound. If *typed* is True, arguments of different data types will be cached separately. For example, f(1.0) and f(1) will be memoized distinctly.Syntax :lru_cache(maxsize=128, typed=False)Example:from functools import lru_cache  @lru_cache(maxsize = None)def factorial(n):    if n<= 1:        return 1    return n * factorial(n-1)print([factorial(n) for n in range(7)])print(factorial.cache_info())Output :[1, 1, 2, 6, 24, 120, 720]
CacheInfo(hits=5, misses=7, maxsize=None, currsize=7)

LRU_cache is a function decorator used for saving up to the maxsize most recent calls of a function. This can save time and memory in case of repeated calls with the same arguments.If *maxsize* is set to None, the cache can grow without bound. If *typed* is True, arguments of different data types will be cached separately. For example, f(1.0) and f(1) will be memoized distinctly.
Syntax :
lru_cache(maxsize=128, typed=False)
Example:
from functools import lru_cache  @lru_cache(maxsize = None)def factorial(n):    if n<= 1:        return 1    return n * factorial(n-1)print([factorial(n) for n in range(7)])print(factorial.cache_info())
Output :
[1, 1, 2, 6, 24, 120, 720]
CacheInfo(hits=5, misses=7, maxsize=None, currsize=7)

SingleDispatchIt is a function decorator. It transforms a function into a generic function so that it can have different behaviors depending upon the type of its first argument. It is used for function overloading, the overloaded implementations are registered using the register() attribute of theExample:from functools import singledispatch  @singledispatchdef fun(s):    print(s)@fun.register(int)def _(s):    print(s * 2)  fun('GeeksforGeeks')fun(10)Output :GeeksforGeeks
20

Example:
from functools import singledispatch  @singledispatchdef fun(s):    print(s)@fun.register(int)def _(s):    print(s * 2)  fun('GeeksforGeeks')fun(10)
Output :
GeeksforGeeks
20

python-modules
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.