加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 使用C API创建一个numpy自定义类对象数组

发布时间:2020-12-16 21:32:21 所属栏目:Python 来源:网络整理
导读:使用C API,我想创建一个包含Quaternion类型对象的numpy数组,这是我用C编写的类.我已经有一个这样的数组(实际上是一个std :: vector),我想制作一个副本 – 或者如果可能的话使用相同的内存. 由于这不是一个基本类型,我需要使用Py_Object类型,并且不能使用PyAr
使用C API,我想创建一个包含Quaternion类型对象的numpy数组,这是我用C编写的类.我已经有一个这样的数组(实际上是一个std :: vector),我想制作一个副本 – 或者如果可能的话使用相同的内存.

由于这不是一个基本类型,我需要使用Py_Object类型,并且不能使用PyArray_SimpleNew或类似的任何容易.

我猜我可能想要使用PyArray_NewFromDescr甚至PyArray_SimpleNewFromDescr,但我完全和完全失去了如何创建我需要描述我的Quaternion类的PyArray_Descr对象.

谁能给我一些关于如何制作那个descr对象的指针?或者让我更好地了解如何构建我的numpy数组?

这基本上是this question的更通用版本,没有分心.

编辑:

使用dastrobu的提示和我的SWIG包装器,我找到了一种方法.我知道不是每个人都在使用SWIG,但对于那些人来说,my answer on my other question显示了我是如何使用SWIG的.

解决方法

由于Quaternion不是直接数字类型,因此您的数组必须将numpy.object作为dtype.因此,您可以使用PyArray_SimpleNew(…,NPY_OBJECT)来创建数组并填充数据.
问题是你的Quaternion类不是python类型.因此,使用对Quaternion类型的对象的引用来填充数组将不起作用. (在这种情况下,如果从python中填充四元数的数组中提取元素,您会发生什么?)
相反,您需要使用PyQuaternion之类的东西包装Quaternion类.包装器负责引用计数和内存管理.它看起来像:
typedef struct {
    PyObject_HEAD
    Quaternion *q;
}PyQuaternion;

static PyTypeObject PyQuaternion_Type = {
    PyObject_HEAD_INIT(NULL)
    0,/*ob_size*/
    "Quaternion",/*tp_name*/
    sizeof(PyQuaternion),/*tp_basicsize*/
/* ... */
};


static PyObject *
PyQuaternion_new(PyTypeObject *type,PyObject *args,PyObject *kwds){
/* ... */
};

static int 
PyQuaternion_init(PyQuaternion *self,PyObject *kwds){
/* ... */
};

static void PyQuaternion_dealloc(PyQuaternion *self){
/* ... */
};

此外,您可以为PyQuaternionType定义自己的C-API,允许您从Quaternions创建PyQuaternions

static PyObject *
PyQuaternion_New(Quaternion *q){
    PyQuaternion *self;
    self = (PyQuaternion *)PyQuaternion_Type.tp_new(type,NULL,NULL);
    self->q = q; 
    return (PyObject *)self;
}

请注意,自我> q将由PyQuaternion_dealloc函数处理,因此请考虑内存管理.最简单的方法是将所有权传递给包装器,让PyQuaternion_dealloc解除分配自我> q.

PyQuaternion_New函数允许您包装Quaternion对象并将它们填充到任何python容器中,如列表,元组,当然还有ntype = numpy.object的numpy数组.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读