当参数是对象实例并且缓存需要查看实例属性时,如何 lru_cache 函数?

Anu*_*hav 5 caching lru python-3.x

我正在尝试在一个以 python 对象作为参数的函数上实现 lru_cache 。仅当函数的参数属性未更改时,该函数才应返回缓存值。然而,看起来 lru_cache 只对函数参数进行“浅层查看”以查看发生了什么变化,并忽略任何属性更改。

例如,在下面的函数中calculate,用 修饰的函数lru_cache接受单元格实例并返回基于实例属性的计算。

from functools import lru_cache

class Cell:

    def __init__(self, x, y):
        self.x =x
        self.y =y


@lru_cache()
def calculate(cell):
    return cell.x + cell.y
Run Code Online (Sandbox Code Playgroud)

运行此命令时:

if __name__ == '__main__':

    cellA = Cell(1,2)
    print(calculate(cellA))
    #returns 3 correctly

    #let's change cellA's attribute of x to something else
    cellA.x = 10

    print(calculate(cellA))
    #also returns 3, but should return 12!
Run Code Online (Sandbox Code Playgroud)

我希望对函数的第二次调用实际上使用缓存的值,因为属性 x 现已更改。

一个非常不优雅的解决方法是将“假参数”传递给计算函数,如下所示:

@lru_cache()
def calculate(cell, prec):
    return cell.x + cell.y

if __name__ == '__main__':

    cellA = Cell(1,2)
    print(calculate(cellA, prec=cellA.x))
    #returns 3

    #let's change cellA's attribute of x to something else
    cellA.x = 10


    print(calculate(cellA, prec=cellA.x))
    #now returns 12!
Run Code Online (Sandbox Code Playgroud)

上面的方法可行,但似乎是一个不好的方法。