Функция ruby, которую вы объясняете, называется «method_missing» http://rubylearning.com/satishtalim/ruby_method_missing.htm .
Это совершенно новая функция, которая присутствует только в некоторых браузерах, таких как Firefox (в движке Javascript для паука-паука). В SpiderMonkey это называется «__noSuchMethod__» https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod
Пожалуйста, прочитайте эту статью от Yehuda Katz http://yehudakatz.com/2008/08/18/method_missing-in-javascript/ для получения более подробной информации о предстоящей реализации.
Современные версии functools.wraps
устанавливают исходную функцию в качестве атрибута __wrapped__
в создаваемых ими оболочках. (Можно найти в __closure__
вложенные функции, обычно используемые для этой цели, но можно использовать и другие типы.) Разумно ожидать, что любая оболочка будет следовать этому соглашению.
Альтернативой является наличие постоянной оболочки, которой можно управлять с помощью флага , чтобы его можно было включать и отключать, не удаляя и не восстанавливая его. Это имеет то преимущество, что оболочка может сохранять свое состояние (здесь кэшированные значения). Флаг может быть отдельной переменной (, например, , другой атрибут объекта, несущего упакованную функцию, если таковой имеется) или может быть атрибутом самой оболочки.
Вы сделали вещи слишком сложными. Декоратор может быть просто удален с помощью del self._greedy_function
. Нет необходимости в атрибуте __wrapped__
.
Вот минимальная реализация методов set_cache
и unset_cache
:
class LRU(OrderedDict):
def __init__(self, maxsize=128, *args, **kwargs):
# ...
self._cache = dict()
super().__init__(*args, **kwargs)
def _greedy_function(self):
time.sleep(1)
return time.time()
def set_cache(self):
self._greedy_function = lru_cache(self._cache)(getattr(self, "_greedy_function"))
def unset_cache(self):
del self._greedy_function
Используя ваш декоратор lru_cache
, вот результаты
o = LRU()
o.set_cache()
print('First call', o._greedy_function())
print('Second call',o._greedy_function()) # Here it prints out the cached value
o.unset_cache()
print('Third call', o._greedy_function()) # The cache is not used
Выходы [ 1111]
First call 1552966668.735025
Second call 1552966668.735025
Third call 1552966669.7354007