3

我有一个这样写的类或扩展类型cython

cdef class Self_Organized_Map:
     cdef 
     def __cinit__(self,np.ndarray data,.....):
     ....

cython我使用这个文件(它的名字是som.pyx)创建了一个python模块distutils,然后我将它导入python并用它来创建和训练一个模型,但是当我想使用pickle它保存我的模型时,我会遇到这个错误:

类型错误:无法腌制 som.Self_Organized_Map 对象

泡菜或我的代码有什么问题?泡菜不能保存扩展对象吗?

4

2 回答 2

5

Cython 类默认情况下不可腌制,因此您需要自己实现Pickle 接口。您可以在许多不同的级别上执行此操作,但这__getstate____setstate__对用户最友好的级别,因此除非您有充分的理由,否则这是一个很好的起点。

如果类的内容是可腌制的,那么就像返回它们的元组 in__getstate__和 in 中的反向操作一样简单__setstate__。Memoryviews 本身不是可腌制的,但具有base可能的属性。

cdef class C:
    cdef double[:] array
    cdef python_obj
    cdef int integer

    def __init__(self,array,python_obj,integer):
        self.array = array
        self.python_obj = python_obj
        self.integer = integer

    def __getstate__(self):
        return (self.array.base, # memoryviews aren't pickleable, need to get underlying object
                          # and hope it's pickleable
                self.python_obj, self.integer)

    def __setstate__(self,x):
        self.array, self.python_obj, self.integer = x

如果您的类包含 C 或 C++ 对象,那么它会复杂得多。对于简单类型的好地方,只需将内存复制到字节数组或利用 Cython 的默认struct<->dict互转换。但是,如果该类包含指针,那么这将不起作用,您需要在 C/C++ 中为其实现可靠的加载/保存机制。

于 2017-05-05T07:36:59.407 回答
3

从 Cython 0.26(2017 年 7 月发布)开始,只要 cdef 类不包含指针或联合,就可以自动腌制它们。对于包含结构的类,可以使用@cython.auto_pickle(True)装饰器启用自动酸洗。由于高代码开销和其他原因,默认情况下禁用它。

更多信息可以在更新日志Stefan Behnel 的网站上找到。

于 2017-07-26T11:32:48.107 回答