随着我们在 Python 世界里编织出越来越复杂的程序,经常会发现自己在不停地重复相同的操作:一次又一次地调用同一个函数、使用同样的输入、执行相同的计算……就像一台忘了自己昨天做过什么的机器,白白浪费了宝贵的算力和时间。
好在,Python 的 functools
模块来拯救我们了。它内置了一系列“高阶工具”,帮你在不改动函数本身的前提下,轻松重用逻辑、提升可读性、压榨性能。下面,就让我带你逐个揭秘,这些轻量级宝藏该怎么用。
从“记忆”开始:lru_cache
想象一下:每次你算完一个结果,都留个“备份”,下次再遇到同样的输入,就直接抄作业,不必重头演算。lru_cache
(Least Recently Used Cache)就是这么神奇,只要在函数上加个装饰器,它就帮你把历史结果记到“小本子”里:
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(35))
-
maxsize
决定“作业本”能写多少条记录,设置为None
则无限制。 -
对于经典的递归、频繁的 API 调用、耗时的数据库查询,它能让运行速度从“分”级骤降到“毫秒”级秒杀。
一行搞定聚合:reduce
要把一长串数据一口气“压缩”为一个值,最直观的做法是写个 for
循环。可若你想写得更简洁、更函数式,reduce()
就能派上用场:
from functools import reduce
numbers = [2, 3, 4]
result = reduce(lambda x, y: x * y, numbers)
print(result) # 输出 24
它依次拿出 x, y
,应用你给的函数,一直“合并”到只剩下一个结果。写成一行,逻辑一目了然,也少了样板式的循环变量。
装饰器的“身份证”:wraps
自己动手写装饰器,往往会遗失原函数的名字和文档(__doc__
)。这样一来,调试和自动化文档就会闹乌龙。只要在 wrapper 上加个 @wraps(func)
,身份就能照单全收:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# ……插入前置或后置逻辑……
return func(*args, **kwargs)
return wrapper
@my_decorator
def greet():
"""简单说声你好"""
print("Hello!")
print(greet.__name__) # 仍然是 "greet"
print(greet.__doc__) # "简单说声你好"
这样,不管你套了多少层装饰,函数依旧“我行我素”,不改身份证,调试更轻松,文档更靠谱。
预设参数神器:partial
有时候,你写了个通用函数,频繁需要“锁定”几个参数再复用——这时 partial
就好比给你的函数做了“微调”,输出一版定制版本:
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5)) # 25
print(cube(2)) # 8
-
square(5)
底层其实跑的是power(5, 2)
,cube(2)
则是power(2, 3)
。 -
用在 map
、filter
、回调函数里,更显简洁与优雅。
更简单的缓存:cache
(Python 3.9+)
如果你用的是 3.9 及以上版本,想要无限制缓存,只要一个更简洁的写法:
from functools import cache
@cache
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
等同于 @lru_cache(maxsize=None)
,让纯函数的天堂更纯粹。
一键补全比较:total_ordering
给类写比较方法,少不了 __lt__
、__gt__
、__eq__
……多达六个。如果你只想定义“等于”+“小于”,就用 @total_ordering
让它自动生成剩下的:
from functools import total_ordering
@total_ordering
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __eq__(self, other):
return self.pages == other.pages
def __lt__(self, other):
return self.pages < other.pages
b1 = Book("深度思考", 200)
b2 = Book("高效学习", 300)
print(b1 < b2) # True
print(b1 >= b2) # False
如此一来,<=
, >
, >=
, !=
……都由 total_ordering
自动搞定,类定义清爽又易维护。
小结:让代码更聪明一点
-
速度提升: lru_cache
/cache
一键记忆,省去重复计算。 -
简洁优雅: partial
、reduce
让逻辑高度抽象,一行搞定循环或参数预设。 -
可维护性: wraps
保留函数元信息,total_ordering
自动补全比较套件。
别小看这些“轻量工具”,它们能让你的 Python 代码更简练、更高效、更易读。下次再敲那些重复逻辑时,不妨先想想:functools 有没有更优雅的解决方案?
作者寄语
如果这篇教程对你有所帮助,欢迎关注和留言。未来我还会分享更多 Python 深度技巧与实战心得,咱们下次见!
– END –