Модуль Pickle, который импортирует код с привязками C - PullRequest
1 голос
/ 23 марта 2020

У меня есть класс, который я хочу использовать с помощью этой функции:

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 . Это оболочка Python для некоторого кода C, которая выполняет быструю выборку из распределения Polya-гамма. Когда я пытаюсь перехватить свой класс, я получаю эту ошибку:

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__

1 Ответ

1 голос
/ 23 марта 2020

К сожалению, похоже, что библиотека Pypolyagamma, которую вы используете, в настоящее время не поддерживает выбор / удаление этих объектов, одним словом: вы не можете выбрать их без изменения библиотеки.

Более того, поскольку она переносится класс C ++, средство выбора / удаления не является тривиальным; ему нужно было бы знать, в каком состоянии из этот обернутый класс необходим для того, чтобы объект находился в том же состоянии после расслоения.

...