问题
I am making my first attempt at porting Python code to Cython. I only have very limited experience with C. I am trying to make a relatively simple class that stores multidimensional arrays. For the purpose of this question, let's leave it to a single one-dimensional array of length 1 for the attribute time. Currently, I am recieving the error:
cdef np.ndarray[np.int64_t, ndim=1] time = np.empty([1], dtype=np.int64)
^
------------------------------------------------------------
data.pyx:22:40: Cannot assign default value to fields in cdef classes, structs or unions
Here are the most relevant files.
data.pyx
import numpy as np
cimport numpy as np
cdef extern from "data_extern.h":
cppclass _Data "Data":
np.int64_t time64[1]
double x_coord, y_coord, z_coord
_Data(np.int64_t *time, double x, double y, double z)
cdef class Data:
cdef _Data *thisptr
cdef np.ndarray[np.int64_t, ndim=1] time = np.empty([1], dtype=np.int64)
def __cinit__(self, np.int64_t time[1], x, y, z):
self.thisptr = new _Data(&time[0], x, y, z)
def __dealloc__(self):
del self.thisptr
data_extern.h
#ifndef DATA_EXTERN_H
#define DATA_EXTERN_H
class Data {
public:
signed long long time64[1];
double x_coord, y_coord, z_coord;
Data();
Data(signed long long time[1], double x, double y, double z;
~Data();
};
#endif
data_extern.cpp
#include <iostream>
#include "data_extern.h"
Data::Data () {}
// Overloaded constructor
Data::Data (signed long long time[1], double x, double y, double z {
this->time64 = time[0];
this->x_coord = x;
this->y_coord = y;
this->z_coord = z;
}
// Destructor
Data::~Data () {}
I recognize there could be multiple problems with my code, but if someone could provide an explanation for the error message it would be much appreciated.
回答1:
The problem is as stated in the error message: you cannot set a default value for a cdef class's C-level properties. You can get around this by setting the value in the __cinit__
constructor as follows:
cdef class Data:
cdef _Data *thisptr
cdef np.ndarray[np.int64_t, ndim=1] time
def __cinit__(self, np.int64_t time[1], x, y, z):
self.thisptr = new _Data(&time[0], x, y, z)
self.time = np.empty([1], dtype=np.int64)
def __dealloc__(self):
del self.thisptr
As a heads-up though, the whole np.ndarray syntax is rather out of date. Unless you are dead-set on using numpy types (which seem to be unnecessary in your code since you are interfacing with a c++ library of some sort), you can use the more modern typed memoryview syntax. You could import the sized integer types using from libc.stdint cimport *
to use those instead of the numpy ones.
来源:https://stackoverflow.com/questions/60159909/cython-cannot-assign-default-value-to-fields-in-cdef-classes-structs-or-unions