什么是SwigPyObject对象?

23

在尝试保存自定义对象时,我遇到了一个错误:

with open(path + '/' + 'my_object.pickle', 'wb') as handle: pickle.dump(my_class_instance, handle, protocol=pickle.HIGHEST_PROTOCOL)

错误信息如下:

TypeError: 无法对 SwigPyObject 对象进行 pickling

我的第一个问题是:什么是 SwigPyObject 对象?这样我就可以尝试找出错误的原因。

1个回答

17

什么是SWIG?

SWIG(简化封装和接口生成器)是一个开源软件工具,用于将使用C或C++编写的库与诸如Python之类的脚本语言连接起来。 SWIG的一个知名替代品是Boost。 Boost库旨在实现相同的功能。

您可以使用SWIG创建使用C / C ++开发的Python库(用于与现有的C / C ++库进行互操作性或提高性能等)。

引用SWIG文档

为了构建Python扩展模块,SWIG使用分层方法,其中扩展模块的某些部分定义在C中,其他部分定义在Python中。 C层包含低级包装器,而Python代码用于定义高级功能。

这种分层方法认识到了每种语言都可以更好地完成扩展构建的某些方面(而不是尝试在C或C ++中完成所有操作)。此外,通过在两种语言中生成代码,您可以获得更多的灵活性,因为您可以使用任一语言的支持代码增强扩展模块。

什么是SwigPyObject对象?

SwigPyObject对象在SWIG文档中关于Python类接口的详细信息主题中描述。

此对象是一个实现细节。它由以下C结构定义:

typedef struct {
    PyObject_HEAD
    void *ptr;
    swig_type_info *ty;
    int own;
    PyObject *next;
    PyObject *dict;
} SwigPyObject;

SwigPyObject对象存储一个C++对象的实例:

当使用 -builtin 选项时,纯Python层会被剥离。每个封装的类都将变成一个新的Python内置类型,该类型继承自SwigPyObject,并且从封装的方法中直接返回 SwigPyObject 实例。

pickle文件

您pickle文件中包含的数据包含一个SwigPyObject对象,但您的解释器不知道如何进行反序列化。您需要检查您的虚拟环境中是否包含提供pickle对象的Python / C ++库。


7
有什么建议可以解决这个问题吗? - AlexAMC
1
这个问题没有简单的解决方案。C++库可能具有一些非常模糊的内存布局,无法存储。考虑在C++中使用链表。列表对象将是一个结构体,其中包含指向第一个和最后一个对象的指针。可以对其进行pickle处理,但在下一次运行中,那里的内存地址将无效。此外,所有列表节点都必须被存储。C++库需要提供自己的序列化。或者将所有数据复制到Python中,并在那里进行pickle处理。 - Martin Ueding

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接