You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当函数参数顺序不影响结果时,如何部署缓存?

实现交换律函数的缓存忽略参数顺序

当然可以,核心思路是统一缓存键的参数顺序,让func(a,b)和func(b,a)生成相同的缓存键,从而复用已有缓存。以下是几种实用方案:

方案1:在函数内部标准化参数顺序

直接在被缓存的函数里先调整参数顺序,确保每次处理的参数都是固定顺序的:

from functools import cache

@cache
def func(a, b):
    # 标准化参数顺序:保证a <= b(需参数支持比较操作)
    if a > b:
        a, b = b, a
    # 原函数逻辑示例
    return a + b

如果参数是不可直接比较的自定义对象,可以给对象实现__lt__方法,或者用sorted结合自定义key:

from functools import cache

class Item:
    def __init__(self, id):
        self.id = id
    def __hash__(self):
        return hash(self.id)
    def __lt__(self, other):
        # 基于id属性比较排序
        return self.id < other.id

@cache
def func(item1, item2):
    # 用sorted统一参数顺序
    item_a, item_b = sorted([item1, item2])
    # 原函数逻辑
    return item_a.id + item_b.id

方案2:自定义交换律缓存装饰器

如果不想修改原函数逻辑,可以封装一个专门的装饰器,自动处理参数排序后再缓存:

from functools import cache, wraps

def commutative_cache(func):
    @wraps(func)
    def wrapper(*args):
        # 对传入的参数排序,生成统一的参数元组
        sorted_args = tuple(sorted(args))
        # 内部定义被缓存的函数,复用原函数逻辑
        @cache
        def cached_func(*sorted_args):
            return func(*sorted_args)
        return cached_func(*sorted_args)
    return wrapper

# 使用装饰器
@commutative_cache
def func(a, b):
    return a + b

这个装饰器支持任意数量的交换律参数(只要参数可哈希、可排序),而且不会污染原函数的代码逻辑。

注意事项

  • 所有参数必须是可哈希的:这是@cache的基本要求,否则无法生成缓存键。
  • 参数需支持排序:如果是自定义对象,需实现__lt__方法,或者在sorted中指定key参数来定义排序规则。

内容的提问来源于stack exchange,提问作者jonnybolton16

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:02:39