【发布时间】:2020-05-27 13:26:33
【问题描述】:
我无法在 Cython 中创建一个简单的类。在 C++ 包装器中处理数组的内存视图相关的文档很少。我想创建一个具有时间、x、y 和 z 属性的数据类。我需要这些属性是数组,最终可以在 Python 中调用。我以前使用 numpy 类型进行此工作,但我想使用 memoryviews 正确执行此操作。我的C++背景不强。目前,我只是想让 time 属性与单元素一维数组一起使用。当我尝试构建我的扩展时,我收到以下错误:
self.c_data = new _Data(&date[1], x, y, z)
^
------------------------------------------------------------
data.pyx:18:32: Cannot take address of memoryview slice
如果我无法获取 memoryview 切片的地址,我该如何初始化我的类属性?这是相关代码。
数据.pyx
# distutils: language = c++
import numpy as np
cimport numpy as np
from cython.view cimport array as cvarray
from . cimport Data
cdef class Data:
cdef _Data *c_data
cdef long[::1] date
def __cinit__(self, long[::1] *date, x, y, z):
self.c_data = new _Data(&date[1], *date, x, y, z)
self.date = cvarray(shape=(1), itemsize=sizeof(long), format="i")
def __dealloc__(self):
del self.c_data
数据.pxd
cdef extern from "data extern.cpp":
pass
cdef extern from "data extern.h":
cppclass _Data "Data":
long date[1]
double x, y, z
Data() except +
_Data(long[:], double, double, double) except +
data_extern.h
#ifndef DATA_EXTERN_H
#define DATA_EXTERN_H
class Data {
public:
long date[1];
double x, y, z;
Data();
Data(long date[1], double x, double y, double z);
~Data();
};
#endif
data_extern.cpp
#include <iostream>
#include "data extern.h"
// Default constructor
Data::Data () {}
// Overloaded constructor
Data::Data (long date[1], double x, double y, double z) {
this->date = date[0];
this->x = x;
this->y = y;
this->z = z;
}
// Destructor
Data::~Data () {}
我的代码可能还有其他问题。如果有人对我如何创建一个可从 python 调用并使用 cython memoryviews 的类有任何见解,将不胜感激。
【问题讨论】:
-
既然您在your last question 中提到它作为假设:您是否打算将
date参数的长度硬编码为单个long的数组,或者您是否尝试支持任意长度的数组?如果您在 c++ 代码的构造函数中使用long *,您知道long *指向的项目数吗? -
明天会在不那么累的时候写一个更有凝聚力的答案,但是由于您的 @property 函数只是简单的变量获取器和设置器,您可以查看将
cdef class Date中的属性声明为public(如果您希望它们不能从 python 端修改但仍然暴露,您可以查看readonly)。 -
感谢您的帮助。对于日期,它可能是一个长度为 1 的数组,但我希望可以选择它是可扩展的。对于剩余的数组,它们都将是动态 3D 或 4D 数组(或向量的向量)。我希望它们可以从 Python 端修改,所以我会考虑将它们设置为 public。
-
所以没有。 x、y 和 z 实际上每个都是 3 维数组(最少)。我的实际代码有 u、v 和 w,它们代表 3D 网格中的速度。我只是想在我的例子中简化一些事情,并且只考虑我的问题的一维时间。但是,是的,我的目标是最终为这些变量中的每一个提供多维数组。我希望我可以在 C++ 端实例化 3D 数组,但如果我愿意,可以选择从 Python 访问它们。所以我的数组将是 u、v、w 的三维数组,尺寸为 x、y、z(至少,可能是时间暗淡)。
-
理想情况下,数组将从 netcdf 文件传递到 C++ 数组,其中包含所有 3D 数组的 C++ 类实例,因此我可以对它们执行进一步的操作,例如插值。
标签: python c++ arrays cython memoryview