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

Python functools.lru_cache的typed参数未按文档描述工作

关于functools.lru_cache中typed参数的误解澄清

你遇到的问题其实是测试例子没选对,误把lru_cache对特定类型的缓存键优化当成了typed参数的作用。先给你拆解清楚:

首先,官方文档里的typed=True,核心作用是当两个参数值相等(a == b为真)、哈希值也相同,但类型不同时,会被当成独立的调用分别缓存。而你的例子里,4(int)和4.0(float)虽然值相等、哈希相同,但因为lru_cache对部分类型有特殊优化,导致它们的缓存键生成逻辑不一样,和typed参数无关:

  • int属于源码定义的fasttypes集合(包含int, str, frozenset, type(None)),单个int参数会直接用参数值作为缓存键;
  • float不属于fasttypes,单个float参数会被包装成_HashedSeq((4.0,))作为缓存键。

这两个键完全不同,所以不管typed设成True还是False,都会被当成不同的缓存条目。

正确展示typed参数差异的例子

要看到typed的实际作用,得找两个值相等、哈希相同、类型不同,且缓存键生成逻辑一致的参数,比如自定义类实例和int:

from functools import lru_cache

class MyInt:
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        # 让MyInt实例和int可以比较相等
        if isinstance(other, int):
            return self.value == other
        return isinstance(other, MyInt) and self.value == other.value
    def __hash__(self):
        # 哈希值和对应int一致
        return hash(self.value)

# 测试typed=False的情况
@lru_cache(typed=False)
def f1(x):
    print(f"f1被调用,参数:{x}")
    return x.value if isinstance(x, MyInt) else x

print("=== typed=False ===")
f1(5)          # 首次调用,打印日志
f1(MyInt(5))   # 值相等、哈希相同,且typed=False,直接命中缓存,无日志输出
print(f1.cache_info())  # 输出 hits=1, misses=1

# 测试typed=True的情况
@lru_cache(typed=True)
def f2(x):
    print(f"f2被调用,参数:{x}")
    return x.value if isinstance(x, MyInt) else x

print("\n=== typed=True ===")
f2(5)          # 首次调用,打印日志
f2(MyInt(5))   # typed=True会区分参数类型,重新调用并打印日志
print(f2.cache_info())  # 输出 hits=0, misses=2

运行这段代码就能看到明显差异:

  • typed=False时,f1(5)和f1(MyInt(5))共享同一个缓存;
  • typed=True时,两者会被当成完全不同的调用,各自生成缓存条目。

总结

你的测试例子里的现象是lru_cache对fasttypes的特殊优化导致的,和typed参数的核心功能无关。只有当参数满足「值相等、哈希相同、类型不同」且缓存键生成逻辑一致时,typed参数才会体现出差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:01:07