我可以创建一个 PyObject*(numpy.float32)吗
我正在尝试在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语言的float类型,这在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 个回答
1
这个简单的模块可以把C语言中的浮点数转换成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'>