开发人员的宝库——Python functools模块
为什么使用functools?
functools 提供高阶函数,这些函数是对其他函数进行操作的函数。这可能意味着返回一个函数,将一个函数作为参数,或两者兼而有之。这些工具非常适合创建装饰器、缓存结果以及改变我们处理函数和方法的方式。
以下是 functools 模块中每个函数的细分:
1.functools.reduce()
reduce() 将二进制函数累积应用于可迭代对象的项,将其简化为单个值。
from functools import reduce
# Example: Calculate the product of a list of numbers
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # Output: 120
- 在要执行累积操作(如对列表中的元素求和或相乘)时使用 reduce() 。与循环相比,此函数是一个更优雅的解决方案,但对于复杂的操作来说,可读性可能较差。
2.functools.partial()
partial() 允许修复一定数量的函数参数并创建一个参数较少的新函数。
from functools import partial
# Example: Fix the first argument of a multiplication function
def multiply(x, y, z):
return x * y * z
# Create a new function with x fixed at 2
double = partial(multiply, 2)
print(double(3, 4)) # Output: 24 (2 * 3 * 4)
- 用于 partial() 在重复传递相同参数时简化函数调用。它非常适合创建更具可读性和可重用性的代码片段。
- 主要是,如果您传递相同的参数,则可以使用此功能。
3.functools.wraps()
wraps() 是一个修饰器,有助于在将原始函数与另一个函数包装在一起时保持其元数据不变。
from functools import wraps
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
print("Before the function call")
return f(*args, **kwargs)
return wrapper
@my_decorator
def greet():
"""Prints a greeting."""
print("Hello!")
print(greet.__name__) # Output: greet
print(greet.__doc__) # Output: Prints a greeting.
- 在编写修饰器时使用 wraps() ,以确保保留函数的元数据,从而更易于理解和调试代码。
- 它保持了功能的原始状态。
4.functools.lru_cache()
lru_cache() 是一个修饰器,它使用最近最少使用的 (LRU) 缓存来缓存函数调用的结果。
from functools import lru_cache
@lru_cache(maxsize=32)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # Output: 55
print(fibonacci(10)) # Cached result, fast output: 55
- 用于 lru_cache() 优化使用相同参数频繁调用的函数,通过缓存结果来减少计算开销。
- 如果您使用相同的参数调用函数,请使用此函数,这样我们就可以节省计算成本。
5.functools.cache()
它的作用:
cache() 是缓存函数调用结果的装饰器。它是 lru_cache(maxsize=None) 的简写。
如何使用它:
from functools import cache
@cache
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
print(factorial(5)) # Output: 120
print(factorial(5)) # Cached result, fast output: 120
- cache() 用于应在没有大小限制的情况下缓存结果的函数,尤其是当频繁发生具有相同参数的调用时。
- 和 cache 之间的 lru_cache 主要区别在于,当达到 maxsize lru_cache 时 lru_cache ,将删除最近使用最少的缓存项。
6.functools.cached_property()
cached_property() 是类属性的修饰器,用于缓存方法的结果,将其存储起来以供将来访问,而无需重新计算。
from functools import cached_property
class Square:
def __init__(self, side):
self.side = side
@cached_property
def area(self):
print("Calculating area")
return self.side ** 2
square = Square(4)
print(square.area) # Output: Calculating area \n 16
print(square.area) # Output: 16 (cached result, no recalculation)
cached_property() 用于计算成本高昂且不经常更改的属性,或者每次重新计算这些属性效率低下。
7.functools.singledispatch()
它的作用:
singledispatch() 是一个修饰器,用于将函数转换为单调度泛型函数,允许基于第一个参数类型进行不同的实现。
如何使用它:
from functools import singledispatch
@singledispatch
def process(value):
print("Default processing")
@process.register(int)
def _(value):
print("Processing integer:", value)
@process.register(str)
def _(value):
print("Processing string:", value)
process(10) # Output: Processing integer: 10
process("hello") # Output: Processing string: hello
- 当需要处理函数中的多个类型时使用 singledispatch() ,提供一种清晰、有条理的方式来定义特定于类型的行为。
- 在课堂上,需要使用 singlemethoddispatch .
- 当想要限制变量的类型时,可以使用它。
8.functools.cmp_to_key()
它的作用:
cmp_to_key() 将旧式比较函数转换为用于排序的键函数。
from functools import cmp_to_key
def compare(a, b):
return (a > b) - (a < b)
sorted_list = sorted([3, 2, 1], key=cmp_to_key(compare))
print(sorted_list) # Output: [1, 2, 3]
- 当有要与 Python 的排序函数重用的旧比较函数时,请使用 cmp_to_key() 。