functools of python Library

Posted by jrw4 on Sat, 01 Jan 2022 00:25:26 +0100

I'm so lazy. I haven't updated it for a long time. I put the previously summarized documents on the blog to top up. I can't do this!
All right, let's start the second one

The functools module is used for higher-order functions: functions that act on or return other functions.

The functools module has the following functions

  • cmp_to_key
  • partial
  • reduce
  • wraps
  • total_ordering
  • update_wrapper

cmp_to_key

Convert the old style comparison function to the key function.

partial

Returns a new partial object, which will use the positional parameter args and the keyword parameter func when calling. If multiple parameter calls are provided, they are appended to args. If additional keyword parameters are provided, they extend and override keywords.

In [10]: def add(x, y, z):
    ...:     return x+y+z
    ...:

In [11]: sum = partial(add, 3, 4)

In [12]: sum(10)
Out[12]: 17

In [13]: sum = partial(add,)

In [14]: sum(10, 3, 4)
Out[14]: 17

In [15]:

reduce

Add the function of two parameters to the items of the sequence, from left to right, in order to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left parameter, X is the cumulative value, the right parameter, y is the updated value from the sequence. If an optional initializer exists, it is placed before the item in the calculated sequence and used as the default when the sequence is empty. If no initializer is provided and the sequence contains only one item, the first item is returned.

In [17]: def add(x, y):
    ...:     return x+y
    ...:

In [18]: list = [1, 2, 3, 4, 5]

In [19]: reduce(add, list)
Out[19]: 15

Incidentally, there is also a map function in Python, which is similar to reduce and is often used for big data processing
The usage is as follows:

In [22]: def square(x) :
    ...:     return x**2
    ...:

In [23]: map(square, list)
Out[23]: [1, 4, 9, 16, 25]

In [26]: s1 = [1, 3, 5, 7, 9]

In [27]: s2 = [2, 4, 6, 8, 10]

In [28]: map(add, s1, s2)
Out[28]: [3, 7, 11, 15, 19]

wraps

This is a convenient function to call update when defining wrapper functions_ Wrapper () as a function decorator

It can avoid the confusion of function names and documents due to the vulnerability of its decorator. It is recommended to use decorator and wrap

In [37]: def wrapper(func):
    ...:     @wraps(func)
    ...:     def wrapper_function(*args, **kwargs):
    ...:         """this is a decorator function"""
    ...:         return func(*args, **kwargs)
    ...:     return wrapper_function
In [38]: @wrapper
    ...: def wrapped():
    ...:     """This is a decorated function"""
    ...:     print 'wrapped'
In [59]: wrapped.__name__
Out[59]: 'wrapped'

In [60]: wrapped.__doc__
Out[60]: 'This is a decorated function'

Compare the original decorators as follows

In [53]: def decorator(func):
    ...:     def wrapper(*args, **kwargs):
    ...:         """this is a decorator function"""
    ...:         return func(*args, **kwargs)
    ...:     return wrapper
    ...:

In [54]: @decorator
    ...: def wrapped():
    ...:     """This is a decorated function"""
    ...:     print 'wrapped'
In [55]: wrapped.__name__
Out[55]: 'wrapper'

In [56]: wrapped.__doc__
Out[56]: 'this is a decorator function'

total_ordering

Given a class that defines one or more rich comparison sorting methods, the method provides a class decorator. This simplifies the effort of specifying all possible rich comparison operations.

Class must be defined__ lt__ (), le(), gt() or__ ge__ () in addition, the class shall provide a__ eq__ () method.

Although this decorator makes it easy to create fully ordered types with good behavior, it is at the expense of slower execution of comparison methods and more complex stack traces. If performance benchmarks show that this is a bottleneck for a given application, implementing all six rich comparison methods may provide an easy speed boost.

In [4]: @total_ordering
   ...: class Student:
   ...:         def _is_valid_operand(self, other):
   ...:                 return (hasattr(other, "lastname") and
   ...:                         hasattr(other, "firstname"))
   ...:         def __eq__(self, other):
   ...:                 if not self._is_valid_operand(other):
   ...:                         return NotImplemented
   ...:                 return ((self.lastname.lower(), self.firstname.lower()) ==
   ...:                         (other.lastname.lower(), other.firstname.lower()))
   ...:         def __lt__(self, other):
   ...:                 if not self._is_valid_operand(other):
   ...:                         return NotImplemented
   ...:                 return ((self.lastname.lower(), self.firstname.lower()) <
   ...:                         (other.lastname.lower(), other.firstname.lower()))
   ...:

update_wrapper

Update a wrapper function to make it more like a wrapped function.

The main purpose of this function is to wrap the decorated function and return the wrapper in the decorator function. If the wrapper function is not updated, the metadata of the returned function will reflect the definition of the wrapper instead of the original function, which is usually meaningless.

update_wrapper() can be used with callable items other than functions.

Topics: Python