我可以创建PyObject *(numpy.float32)

时间:2012-01-26 17:03:52

标签: python c numpy cython python-c-api

我正在尝试在C(扩展Python)中实现一个函数来返回一个numpy.float32数据类型。是否有可能实际创建一个对象并将其返回,这样在python中从调用该函数返回的对象是numpy.float32的一个实例?

(C扩展名)

PyObject *numpyFloatFromFloat(float d)
{
   ret = SomeAPICall(d)
   return ret;
}

(在python中)

a = something_special()

type(a)
-> numpy.float32

现在所有使用参考文档中记录的API的尝试都说明了如何创建一个产生numpy.ndarray的数组,到目前为止使用数据类型会产生一个C类型的浮点数,它在python中转换为double。由于某种原因,我不知道,我真的需要一个实际的IEEE 754 float32在这个函数的末尾。

到目前为止的解决方案:

something.pyx:

cdef extern from "float_gen.h"
    float special_action(void)

def numpy_float_interface():
    return numpy.float32(special_action())

float_gen.h

static inline float special_action() { return 1.0; }

我在这里没有看到任何数据丢失,但我无法确定。我知道numpy.float32被视为C float或float32_t所以假设当我在pyx文件中调用special_action时它没有将它转换为double(就像python那样)它应该是无损的。

修改 最终的解决方案非常不同,我只需要了解如何使用numpy库在C中正确扩展Python。

下面只返回一个np.float32(32)

static PyObject *get_float(PyObject *self, PyObject *args) {
    float v = 32;
    PyObject *np_float32_val = NULL;
    PyArray_Descr *descr = NULL;
    if(! PyArg_ParseTuple(args, ""))
        return NULL;
    if(! (descr = PyArray_DescrFromType(NPY_FLOAT32))) {
        PyErr_SetString(PyExc_TypeError, "Improper descriptor");
        return NULL;
    }

    np_float32_val = PyArray_Scalar(&v, descr, NULL);
    printf("%lu\n", np_float32_val->ob_refcnt);
    return np_float32_val;
}

1 个答案:

答案 0 :(得分:1)

这个简单的模块从C float返回np.int32。 cdef float并不是必需的,因为np.float32()应该强制你将它提供给np.float32。

test_mod.pyx

import numpy as np
def fucn():
    cdef float a
    a = 1
    return np.float32(a)

tester.py

import pyximport
pyximport.install()
import test_mod

a = test_mod.func()
print type(a) # <type 'numpy.float32'>