вызов метода cache/memoize для разных объектов экземпляров python

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

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

from time import sleep

class Test(object):

    def expensive_calc(self, arg, kwarg1):

        sleep(5)

obj1 = Test()
obj2 = Test()

obj1.expensive_calc(1, kwarg1=1)
obj2.expensive_calc(1, kwarg1=1) # Would like this use the cache

person Max 1000000    schedule 21.04.2018    source источник
comment
Я не понимаю, какое отношение к этому имеет кеш, не могли бы вы объяснить?   -  person Rohi    schedule 21.04.2018
comment
То, что не ясно? Я пытаюсь понять, как кешировать результаты вызова метода вместо того, чтобы каждый раз повторно запускать дорогое_calc(). Код здесь представляет собой упрощенный пример структуры задачи.   -  person Max 1000000    schedule 21.04.2018
comment
Использование слова «кэш» сбивает ее с толку, поскольку оно обычно используется в терминах кэш-памяти процессора. Я теперь понимаю, что вы хотите сделать, у вас постоянное количество аргументов?   -  person Rohi    schedule 21.04.2018
comment
Извините за путаницу, может быть, я должен был написать memoize, чтобы быть более ясным. Функция не имеет аргументов с постоянным числом, но это не должно быть проблемой. Это решенная проблема для обычных функций, если вы используете декоратор memoize, но я пытаюсь заставить его работать для связанного метода класса.   -  person Max 1000000    schedule 21.04.2018
comment
У кого-нибудь есть идеи?   -  person Max 1000000    schedule 26.11.2018


Ответы (1)


Да, вы можете назначать переменные определению класса с помощью self.__class__

Вот пример

class Test:
    def self_assign(self):
        if not hasattr(self.__class__, 'storage'):
            self.__class__.storage = 'useful data'
    def get_self_assign_value(self):
        return getattr(self.__class__, 'storage')

В использовании:

In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:class Test:
  :  def self_assign(self):
   :     if not hasattr(self.__class__, 'storage'):
 :           self.__class__.storage = 'useful data'
  :  def get_self_assign_value(self):
       : return getattr(self.__class__, 'storage')
:<EOF>

In [2]:

In [2]: test1 = Test()

In [3]: test2 = Test()

In [4]: test1.get_self_assign_value()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-88e253d48023> in <module>
----> 1 test1.get_self_assign_value()

<ipython-input-1-e186ef60b5aa> in get_self_assign_value(self)
      4             self.__class__.storage = 'useful data'
      5     def get_self_assign_value(self):
----> 6         return getattr(self.__class__, 'storage')

AttributeError: type object 'Test' has no attribute 'storage'

In [5]: test2.get_self_assign_value()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-60a245b44dc0> in <module>
----> 1 test2.get_self_assign_value()

<ipython-input-1-e186ef60b5aa> in get_self_assign_value(self)
      4             self.__class__.storage = 'useful data'
      5     def get_self_assign_value(self):
----> 6         return getattr(self.__class__, 'storage')

AttributeError: type object 'Test' has no attribute 'storage'

In [6]: test1.self_assign()

In [7]: test1.get_self_assign_value()
Out[7]: 'useful data'

In [8]: test2.get_self_assign_value()
Out[8]: 'useful data'
person sneilan    schedule 02.07.2020