J'ai un décorateur memoize qui utilise le backend cache de Django pour se souvenir du résultat d'une fonction pendant un certain temps. Je l'applique spécifiquement à une méthode de classe.Décorateurs Python et méthodes de classe et évaluation - django memoize
Mon décorateur ressemble:
def memoize(prefix='mysite', timeout=300, keygenfunc=None):
# MUST SPECIFY A KEYGENFUNC(args, kwargs) WHICH MUST RETURN A STRING
def funcwrap(meth):
def keymaker(*args, **kwargs):
key = prefix + '___' + meth.func_name + '___' + keygenfunc(args, kwargs)
return key
def invalidate(*args, **kwargs):
key = keymaker(*args, **kwargs)
cache.set(key, None, 1)
def newfunc(*args, **kwargs):
# construct key
key = keymaker(*args, **kwargs)
# is in cache?
rv = cache.get(key)
if rv is None:
# cache miss
rv = meth(*args, **kwargs)
cache.set(key, rv, timeout)
return rv
newfunc.invalidate = invalidate
return newfunc
return funcwrap
J'utilise ceci sur une méthode de classe, donc quelque chose comme:
class StorageUnit(models.Model):
@memoize(timeout=60*180, keygenfunc=lambda x,y: str(x[0].id))
def someBigCalculation(self):
...
return result
Le processus de memoization réel fonctionne parfaitement! C'est-à-dire qu'un appel à
myStorageUnitInstance.someBigCalculation()
utilise correctement le cache. OK cool!
Mon problème est lorsque je tente d'invalider manuellement l'entrée d'une instance spécifique, où je veux être en mesure d'exécuter
myStorageUnitInstance.someBigCalculation.invalidate()
Cependant, cela ne fonctionne pas, parce que « soi » ne se faire passer et donc la clé ne se fait pas. Je reçois une erreur "IndexError: tuple index out of range" pointant vers ma fonction lambda comme indiqué plus haut.
Bien sûr, je peux appeler avec succès:
myStorageUnitInstance.someBigCalculation.invalidate(myStorageUnitInstance)
et cela fonctionne parfaitement. Mais il "sent" redondant quand je référence déjà une instance spécifique. Comment puis-je faire en sorte que Python traite cette méthode comme une méthode liée à une instance et remplisse donc correctement la variable "self"?