Как динамически удалить декоратор из функции?

Функция 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/ для получения более подробной информации о предстоящей реализации.

4
задан fbparis 18 March 2019 в 04:58
поделиться

2 ответа

Современные версии functools.wraps устанавливают исходную функцию в качестве атрибута __wrapped__ в создаваемых ими оболочках. (Можно найти в __closure__ вложенные функции, обычно используемые для этой цели, но можно использовать и другие типы.) Разумно ожидать, что любая оболочка будет следовать этому соглашению.

Альтернативой является наличие постоянной оболочки, которой можно управлять с помощью флага , чтобы его можно было включать и отключать, не удаляя и не восстанавливая его. Это имеет то преимущество, что оболочка может сохранять свое состояние (здесь кэшированные значения). Флаг может быть отдельной переменной (, например, , другой атрибут объекта, несущего упакованную функцию, если таковой имеется) или может быть атрибутом самой оболочки.

0
ответ дан Davis Herring 18 March 2019 в 04:58
поделиться

Вы сделали вещи слишком сложными. Декоратор может быть просто удален с помощью 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
0
ответ дан gdlmx 18 March 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: