天天看点

Python functools 包:高阶函数和函数工具的利器

作者:AI自由

Python 中的 functools 包是一个强大的工具,提供了许多函数工具和高阶函数,用于增强函数的功能和灵活性。这应该时用python的同学无法拒绝和绕开的一个包吧。

本文将详细介绍 functools 包,并列举其中的常用功能点。

偏函数(Partial Functions)

functools.partial 函数允许我们部分地应用(partial application)一个函数,固定其中的一个或多个参数,从而创建一个新的函数。这对于在调用时不需要重复输入相同参数的函数很有用。示例:

from functools import partial

def multiply(a, b):
    return a * b

double = partial(multiply, b=2)

print(double(5))  # 输出:10           

缓存(Caching)

functools.lru_cache 装饰器提供了一个缓存机制,用于优化函数的性能。它可以缓存函数的结果,避免重复计算,以提高函数的执行效率。

示例:

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(10))  # 输出:55           

函数组合(Function Composition)

functools 包提供了 compose 函数,用于组合多个函数,创建一个新的函数,该函数将按照给定的顺序依次调用这些函数。数据处理中这种应该非常的常用。

示例:

from functools import compose

def add_one(x):
    return x + 1

def multiply_by_two(x):
    return x * 2

transform = compose(add_one, multiply_by_two)

print(transform(5))  # 输出:12           

functools.wraps 装饰器

functools.wraps 装饰器用于保留原始函数的元数据,如 docstring 和函数名等。它在函数装饰器中特别有用。

示例

from functools import wraps

def decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Before function")
        result = func(*args, **kwargs)
        print("After function")
        return result
    return wrapper

@decorator
def greet(name):
    """Greet the person."""
    print(f"Hello, {name}!")

greet("Alice")
print(greet.__name__)  # 输出:greet
print(greet.__doc__)  # 输出:Greet the person.           

functools.reduce 函数

functools.reduce 函数用于对可迭代对象中的元素进行二进制操作,例如求和、乘积等。

示例

from functools import reduce

numbers = [1, 2, 3, 4, 5]
sum_result = reduce(lambda x, y: x + y, numbers)
product_result = reduce(lambda x, y: x * y, numbers)

print(sum_result)  # 输出:15
print(product_result)  # 输出:120           

functools.total_ordering 装饰器

functools.total_ordering 装饰器用于简化自定义类的比较操作。它自动生成 __eq__、__ne__、__lt__、__gt__、__le__、__ge__ 这些比较方法中的一些。

示例:

from functools import total_ordering

@total_ordering
class Person:
    def __init__(self, age):
        self.age = age
    
    def __eq__(self, other):
        return self.age == other.age
    
    def __lt__(self, other):
        return self.age < other.age

p1 = Person(25)
p2 = Person(30)

print(p1 == p2)  # 输出:False
print(p1 != p2)  # 输出:True
print(p1 < p2)  # 输出:True           

functools.cmp_to_key 函数

functools.cmp_to_key 函数用于将旧式的比较函数转换为键函数,以便进行排序等操作。

示例:

from functools import cmp_to_key

def compare_length(a, b):
    if len(a) < len(b):
        return -1
    elif len(a) > len(b):
        return 1
    else:
        return 0

words = ['apple', 'banana', 'cherry', 'date']
sorted_words = sorted(words, key=cmp_to_key(compare_length))

print(sorted_words)  # 输出:['date', 'apple', 'cherry', 'banana']
           

在上述示例中,我们定义了一个旧式的比较函数 compare_length,它比较两个字符串的长度。然后,我们使用 cmp_to_key 函数将其转换为键函数,通过 key 参数将其传递给 sorted 函数进行排序。

functools.partialmethod 类

functools.partialmethod 类用于创建一个部分应用于类方法的可调用对象。

示例

from functools import partialmethod

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height
    
    perimeter = partialmethod(lambda self: 2 * (self.width + self.height))

r = Rectangle(5, 3)
print(r.area())  # 输出:15
print(r.perimeter())  # 输出:16           

在上述示例中,我们定义了一个 Rectangle 类,其中的 perimeter 方法是通过 partialmethod 创建的可调用对象。这样,我们可以直接调用 r.perimeter() 来计算矩形的周长。

这些是 functools 包中的一些其他功能,它们提供了更多灵活性和功能扩展,帮助我们编写更加高效和可读性的代码。

希望本文对您了解和使用 functools 包有所帮助!