травление функции lru_cached на объекте - PullRequest
0 голосов
/ 25 января 2019

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

Начиная с:

import pickle
from functools import lru_cache

class Test:
    def __init__(self):
        self.func = lru_cache(maxsize=None)(self._inner_func)

    def _inner_func(self, x):
        # In reality this will be slow-running
        return x

вызывающий

t = Test()
pickle.dumps(t)

возвращает

_pickle.PicklingError: Can't pickle <functools._lru_cache_wrapper object at 0x00000190454A7AC8>: it's not the same object as __main__.Test._inner_func

которого я не очень понимаю. Кстати, я также попробовал вариант, в котором имя _inner_func также было func, но это ничего не изменило.

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Используйте methodtools.lru_cache, чтобы не создавать новую функцию кэша в __init__

import pickle
from methodtools import lru_cache

class Test:
    @lru_cache(maxsize=None)
    def func(self, x):
        # In reality this will be slow-running
        return x

if __name__ == '__main__':
    t = Test()
    print(pickle.dumps(t))

Требуется установить methodtools через pypi:

pip install methodtools
0 голосов
/ 30 января 2019

Как подробно описано в комментариях, модуль pickle имеет проблемы при работе с декораторами.См. Этот вопрос для более подробной информации:

Pickle и украшенные классы (PicklingError: не тот же объект)

...