天天看點

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 包有所幫助!