📜  Python中的 Functools 模块

📅  最后修改于: 2022-05-13 01:54:47.301000             🧑  作者: Mango

Python中的 Functools 模块

Functools模块用于处理其他函数的高阶函数。它提供了与其他函数和可调用对象一起使用的函数,以使用或扩展它们而无需完全重写它们。这个模块有两个类——部分和部分方法

部分类

偏函数是特定参数值的原始函数。它们可以通过使用 functools 库中的“部分”在Python中创建。 __name____doc__属性将由程序员创建,因为它们不是自动创建的。 partial()创建的对象具有三个只读属性:

句法:

partial(func[, *args][, **keywords])
  • partial.func - 它返回父函数的名称以及十六进制地址。
  • partial.args - 它返回部分函数中提供的位置参数。
  • partial.keywords - 它返回部分函数中提供的关键字参数。

例子:

from functools import partial
  
  
def power(a, b):
    return a**b
  
# partial functions
pow2 = 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)

输出 :

部分方法类

它是针对特定参数(如偏函数)的已定义函数的方法定义。但是,它是不可调用的,而只是一个方法描述符。它返回一个新的部分方法描述符。

句法:

partialmethod(func, *args, **keywords)

例子:

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)

输出 :

black
blue

职能

  • Cmp_to_key

    它将比较函数转换为关键函数。对于不同的条件,比较函数必须返回 1、-1 和 0。可用于sorted()、min()、max()等关键函数。

    句法 :

    function(iterable, key=cmp_to_key(cmp_function)) 

    例子:

    from functools import cmp_to_key
      
    # function to sort according to last character
    def 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)
    

    输出 :

    sorted list : ['for', 'geeks', 'geeks']
    
  • 减少

    它对序列的元素重复应用两个参数的函数,以将序列简化为单个值。例如, reduce(lambda x, y: x^y, [1, 2, 3, 4])计算(((1^2)^3)^4) 。如果初始值存在,则将其放在计算中,如果序列为空则为默认结果。
    句法 :

    reduce(function, sequence[, initial]) -> value  

    例子:

    from functools import reduce
    list1 = [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)
    

    输出 :

    Sum of list1 : 26
    Maximum of list2 : xyz
    
  • Total_ordering
    它是一个类装饰器,用于填充缺失的比较方法(__lt__, __gt__, __eq__, __le__, __ge__) 。如果给定的类定义了一个或多个比较方法,则“@total_ordering”会根据给定的定义自动提供其余部分。但是,该类必须定义__lt__(), __le__(), __gt__(),__ge__() ,此外,该类应提供__eq__()方法。

    例子:

    from functools import total_ordering
      
    @total_ordering
    class 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)= 10 :', N(9)>= N(10))
    print('5 == 5 :', N(5)== N(5))
    

    输出 :

    6 > 2 : False
    3 < 1 : True
    2 = 10 : True
    5 == 5 : True
    
  • 更新包装器

    它更新了一个包装函数,使其看起来像被包装的函数。例如,对于偏函数,我们可以使用 update_wrapper(partial, parent) 将偏函数更新为看起来像它的父函数。这会将部分函数的文档(__doc__)和名称(__name__)更新为与父函数相同。

    句法 :

    update_wrapper(wrapper, wrapped[, assigned][, updated])

    例子:

    from functools import update_wrapper, partial
      
    def power(a, b):
        ''' a to the power b'''
        return a**b
      
    # partial function
    pow2 = 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__)
    

    输出 :

    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
    
  • 包裹
    它是一个函数装饰器,它将 update_wrapper() 应用于装饰函数。它相当于部分(update_wrapper,wrapped=wrapped,assigned=assigned,updated=updated)。

    例子:

    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
      
    @decorator
    def f(x):
        """f's Docstring"""
        return x
      
    print('f name :', f.__name__)
    print('Documentation of f :', f.__doc__)
    

    输出 :

    Documentation of decorated : f's Docstring
    f name : f
    Documentation of f : f's Docstring
    
  • LRU_cache

    LRU_cache 是一个函数装饰器,用于保存最多为 maxsize 最近的函数调用。这可以在使用相同参数重复调用的情况下节省时间和内存。
    如果 *maxsize* 设置为 None,缓存可以无限制地增长。如果 *typed* 为 True,则不同数据类型的参数将分别缓存。例如,f(1.0) 和 f(1) 将被清楚地记住。

    句法 :

    lru_cache(maxsize=128, typed=False)

    例子:

    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())
    

    输出 :

    [1, 1, 2, 6, 24, 120, 720]
    CacheInfo(hits=5, misses=7, maxsize=None, currsize=7)
    
  • 单次派送
    它是一个函数装饰器。它将一个函数转换为一个泛型函数,以便它可以根据其第一个参数的类型具有不同的行为。它用于函数重载,重载的实现使用 register() 属性注册

    例子:

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

    输出 :

    GeeksforGeeks
    20