Skip to content

Latest commit

 

History

History
108 lines (80 loc) · 2.94 KB

File metadata and controls

108 lines (80 loc) · 2.94 KB

Built-ins and libraries

functools

The functools module provides some useful tools for functions, including several decorators.

  • @wraps

    @wraps is useful when creating decorators. It updates the new function to "look like" the original function.

    (Script available)

    from functools import wraps
    
    def decorator(func):
        @wraps(func)
        def __new_func(*args, **kwargs):
            # do stuff
            return func(*args, **kwargs)
    
        return __new_func
    
    @decorator
    def f():
        """
        This is f!
        :return:
        """
        pass
    
    if __name__ == '__main__':
        help(f)  # try removing the @wraps decorator
  • @lru_cache

    @lru_cache lets a function memorize its previous calls and their results, eliminating the need to make repetitive calculations.

    (Script available)

    import sys
    import time
    
    from functools import lru_cache
    
    @lru_cache()
    def fibonacci(n):
        print("Calculating {}".format(n), file=sys.stderr)
        time.sleep(0.1)
        if n <= 0:
            return 0
        if n == 1:
            return 1
        return fibonacci(n - 1) + fibonacci(n - 2)
    
    if __name__ == '__main__':
        print(fibonacci(10))
        print(fibonacci(20))

    There is also the "lru" aspect of the tool, which has a more detailed explanation in the docs.

  • @total_ordering

    Doc:

    Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:

    The class must define one of __lt__(), __le__(), __gt__(), or __ge__(). In addition, the class should supply an __eq__() method.

    (Script available)

    from functools import total_ordering
    
    @total_ordering
    class Integer(object):
        def __init__(self, x):
            self.x = x
    
        def __eq__(self, other):
            return self.x == other.x
    
        def __lt__(self, other):
            return self.x < other.x
    
    if __name__ == '__main__':
        print(Integer(1) >= Integer(2))  # try removing @total_ordering decorator

Prev / Up / Next