Этот вопрос является продолжением ответа для Python сбрасываемого экземпляра метода напоминания декоратора .
На самом деле, я бы написал это как комментарий к этому ответу, но у меня (пока, я надеюсь) недостаточно репутации.
В этом ответе @aix дает хороший подход к сбросу запомненных функций с помощью декораторов.
«Проблема» с этим ответом состоит в том, что вызов reset
для определенного декорированного метода сбрасывает кэш для всех экземпляров. Пример, использующий те же классы, определенные @aix, должен прояснить:
c = my_class()
print c.my_func(55)
# This time the function is computed and stored in cache
print c.my_func(55)
# This second call is cached... no computation needed
d = my_class()
d.my_func.reset()
print c.my_func(55)
# This third call is also computed, since the cache has been cleared
Я думаю, что d.my_func.reset()
должен очищать кэш только для предварительно вычисленных значений d.my_func
, а не для всех других экземпляров my_class
.
У меня есть полу-решение, которое не убеждает полностью, но я думаю, что кто-то может улучшить.
Я изменил метод reset()
и ввел параметр instance
:
def _reset(self,instance):
for cached in self.cache.keys():
if cached[0] == instance:
del self.cache[cached]
Теперь, если я сделаю:
c = my_class()
print c.my_func(55)
# This time the function is computed and stored in cache
print c.my_func(55)
# This second call is cached
d = my_class()
d.my_func.reset(d)
print c.my_func(55)
# Now this third call is cached
Однако способ вызова метода сброса: d.my_func.reset(d)
кажется (по крайней мере) уродливым, но я не смог найти лучшего решения ... У кого-нибудь есть идеи?
Спасибо!
Редактировать
Для записи: вместо передачи экземпляра в качестве параметра, вы можете получить то же поведение, изменяя метод декоратора __get__
.
Добавьте self.original_self = obj
в методе __get__(self, obj, objtype)
и замените if cached[0] == instance
на if cached[0] == self.original_self
в методе _reset
. Это решает проблему!