【问题标题】:Cython "Cannot assign default value to fields in cdef classes, structs or unions"Cython“无法为 cdef 类、结构或联合中的字段分配默认值”
【发布时间】:2020-02-10 23:20:51
【问题描述】:

我第一次尝试将 Python 代码移植到 Cython。我只有非常有限的 C 经验。我正在尝试制作一个相对简单的类来存储多维数组。出于这个问题的目的,让我们将属性时间留给长度为 1 的单个一维数组。目前,我收到错误消息:

    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

这里是最相关的文件。

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

我认识到我的代码可能存在多个问题,但如果有人能对错误消息提供解释,我们将不胜感激。

【问题讨论】:

    标签: python arrays python-3.x cython cythonize


    【解决方案1】:

    问题如错误消息中所述:您无法为 cdef 类的 C 级属性设置默认值。您可以通过在__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 类型。

    【讨论】:

    • 是的。这确实让我超越了默认值错误。我将尝试使用 memoryview 语法。谢谢!
    • 我在这里用 memoryview 制作了一个替代解决方案,尽管它使用 long 数组而不是 long long 是无关紧要的。 stackoverflow.com/questions/60180703/…
    猜你喜欢
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多