我想要一个基于身份的Python @cachedecorator ,而不是__hash__/__equal.

也就是说,我希望参数ka的缓存值不用于不同的对象ka2,即使是ka == ka2.

有没有办法做到这一点?

代码:

from functools import cache


class Key:
    def __init__(self, value):
        self.value = value

    def __eq__(self, another):
        print(f"__eq__ {self.value}, {another.value}")
        return another.value == self.value

    def __hash__(self):
        print(f"__hash__ {self.value}")
        return hash(self.value)

    def __repr__(self):
        return self.value


i = 0


@cache
def foo(key):
    global i
    i += 1
    print(f"Computing foo({key}) = {i}")
    return i


ka = Key('a')
ka2 = Key('a')

print(f"foo(ka): {foo(ka)}")
print(f"foo(ka2): {foo(ka2)}")  # I would like the cached value for ka NOT to be used even though ka2 == ka.

推荐答案

制作一个类似于Key的包装器,通过其包装对象的标识进行比较,并将缓存函数包装在使用包装器的助手中:

class Id:
  __slots__="x",
  def __init__(self,x): self.x=x
  def __hash__(self): return id(self.x)
  def __eq__(self,o): return self.x is o.x

def cache_id(f):
  @functools.cache
  def id_f(i): return f(i.x)
  @functools.wraps(f)
  def call(x): return id_f(Id(x))
  return call

@cache_id
def foo(key): …

Python相关问答推荐

Django序列化器没有验证或保存数据

使用Ubuntu、Python和Weasyprint的Docker文件-venv的问题

如何销毁框架并使其在tkinter中看起来像以前的样子?

当密钥是复合且唯一时,Pandas合并抱怨标签不唯一

如何在具有重复数据的pandas中对groupby进行总和,同时保留其他列

使用SciPy进行曲线匹配未能给出正确的匹配

' osmnx.shortest_track '返回有效源 node 和目标 node 的'无'

如何过滤包含2个指定子字符串的收件箱列名?

将pandas Dataframe转换为3D numpy矩阵

如何获得每个组的时间戳差异?

Pre—Commit MyPy无法禁用非错误消息

所有列的滚动标准差,忽略NaN

pandas:排序多级列

当递归函数的返回值未绑定到变量时,非局部变量不更新:

计算分布的标准差

使用groupby方法移除公共子字符串

字符串合并语法在哪里记录

为什么Python内存中的列表大小与文档不匹配?

语法错误:文档. evaluate:表达式不是合法表达式

在极点中读取、扫描和接收有什么不同?