Cython "Невозможно назначить значение по умолчанию для полей в классах, структурах или объединениях cdef" - PullRequest
0 голосов
/ 11 февраля 2020

Я делаю свою первую попытку переноса кода Python на Cython. У меня очень ограниченный опыт работы с C. Я пытаюсь сделать относительно простой класс, который хранит многомерные массивы. Для целей этого вопроса давайте оставим это для одного одномерного массива длины 1 для атрибута time. В настоящее время я получаю сообщение об ошибке:

    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

Вот наиболее важные файлы.

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 () {}

Я понимаю, что может быть несколько проблем с моим кодом, но если кто-то может предоставить объяснение сообщения об ошибке, оно будет очень признательно.

1 Ответ

1 голос
/ 11 февраля 2020

Проблема как указано в сообщении об ошибке: вы не можете установить значение по умолчанию для свойств C -уровня класса cdef. Вы можете обойти это, установив значение в конструкторе __cinit__ следующим образом:

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

Однако, как известно, весь синтаксис np.ndarray устарел. Если вы не настроены на использование типов numpy (которые в вашем коде кажутся ненужными, поскольку вы взаимодействуете с какой-либо библиотекой c ++), вы можете использовать более современный синтаксис typed memoryview . Вы можете импортировать целочисленные типы размера, используя from libc.stdint cimport *, чтобы использовать их вместо numpy.

...