簡體   English   中英

使用 C 綁定導入代碼的 Pickle 模塊

[英]Pickle module that imports code with C bindings

我有一個我想用這個函數腌制的課程:

def _pickle(self):
    """Pickle model instance.
    """
    fpath = f'{directory}/model.pickle'
    with open(fpath, 'wb') as f:
        pickle.dump(self, f, pickle.HIGHEST_PROTOCOL)

但是,在我的文件中,我導入了一個庫PyPolyaGamma 它是一些 C 代碼的 Python 包裝器,可以從 Polya-gamma 分布中快速采樣。 當我嘗試腌制我的課程時,出現此錯誤:

Traceback (most recent call last):
  File "fit_model.py", line 262, in <module>
    model.fit(Y)
  File "/Users/gwg/projects/cdnlvm/kl_gplvmbase.py", line 97, in fit
    self._plot_and_print(t)
  File "/Users/gwg/projects/cdnlvm/kl_nbgplvm.py", line 456, in _plot_and_print
    self._pickle()
  File "/Users/gwg/projects/cdnlvm/kl_gplvmbase.py", line 352, in _pickle
    pickle.dump(self_, f, pickle.HIGHEST_PROTOCOL)
  File "stringsource", line 2, in pypolyagamma.pypolyagamma.PyPolyaGamma.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__

我的理解是 Python 不知道如何序列化 PyPolyaGamma 代碼,可能是因為對 C 的依賴。處理這個問題的正確方法是什么?


這是一個最小且完整的示例,如果您願意安裝 PyPolyaGamma:

# pickle_test.py

import pickle
from   pypolyagamma import PyPolyaGamma

class Model:
    def __init__(self):
        self.pg = PyPolyaGamma()

model = Model()
with open('test.pickle', 'wb+') as f:
    pickle.dump(model, f)

這將輸出:

Traceback (most recent call last):
  File "pickle_test.py", line 15, in <module>
    pickle.dump(model, f)
  File "stringsource", line 2, in pypolyagamma.pypolyagamma.PyPolyaGamma.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__

不幸的是,您使用的 pypolyagamma 庫目前似乎不支持酸洗/取消酸洗這些對象,所以總而言之:您不能在不修改庫的情況下對它們進行酸洗。

此外,由於它包裝了一個 C++ 類,pickler/unpickler 不是微不足道的; 它需要知道該包裝類的什么狀態對於解壓后對象處於相同狀態是必要的。

作為包裝器的替代品,如果您不介意使用功能接口,那么我建議使用polyagamma代替。 這解決了酸洗問題。 它是一個用 C 編寫的用於 Polya-Gamma 變量采樣的 python 包。它很靈活,允許使用不同的采樣方法,並有一個類似於 Numpy 的 API。 您可以通過pip install -U polyagamma安裝最新版本。

暫無
暫無

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

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