I am trying to implement the lru_cache on a function that takes in a python object as an argument. The function should return a cached value only if it's argument's attributes have not changed. However, it looks like the lru_cache only does a "shallow look" into the functions arguments to see what has changed and ignores any attribute changes.
For e.g. in the below the calculate
function which is decorated with lru_cache
takes in a cell instance and returns a calculation based on the instance's attributes.
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
When running this:
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!
I'd like the second call to function to actually not used the cached value as the attribute x has now been changed.
A very inelegant workaround is to pass in "fake arguments" to the calculate function as such:
@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!
The above works but seems like a bad way to go about doing this.