簡體   English   中英

在 object 上酸洗 lru_cached function

[英]pickling lru_cached function on object

作為並行化某些現有代碼(使用多處理)的一部分,我遇到了類似於下面的 class 需要腌制的情況。

從...開始:

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 ,但這並沒有改變。

正如評論中詳述的那樣,pickle 模塊在處理裝飾器時存在問題。 有關更多詳細信息,請參閱此問題:

Pickle 和裝飾類(PicklingError:不是同一個對象)

使用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))

它需要通過pypi安裝methodtools:

pip install methodtools

如果有人感興趣,這可以通過使用 getstate 和 setstate 來解決,如下所示:

from functools import lru_cache
from copy import copy


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

    def __getstate__(self):
        result = copy(self.__dict__)
        result["func"] = None
        return result

    def __setstate__(self, state):
        self.__dict__ = state
        self.func = lru_cache(maxsize=None)(self._inner_func)
   

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM