我是靠谱客的博主 柔弱鸵鸟,最近开发中收集的这篇文章主要介绍python转cython_python – 使用现有C对象初始化Cython对象,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C模型

假设我有以下C数据结构,我希望向Python公开.

#include

#include

struct mystruct

{

int a, b, c, d, e, f, g, h, i, j, k, l, m;

};

typedef std::vector> mystruct_list;

提升Python

我可以使用boost :: python使用以下代码相当有效地包装它们,轻松地允许我使用现有的mystruct(复制shared_ptr)而不是重新创建现有对象.

#include "mystruct.h"

#include

using namespace boost::python;

BOOST_PYTHON_MODULE(example)

{

class_>("MyStruct", init<>())

.def_readwrite("a", &mystruct::a);

// add the rest of the member variables

class_("MyStructList", init<>())

.def("at", &mystruct_list::at, return_value_policy());

// add the rest of the member functions

}

用Cython

在Cython中,我不知道如何从mystruct_list中提取项目,而不复制底层数据.我不知道如何从现有的shared_ptr< mystruct>初始化MyStruct,而不是以各种形式之一复制所有数据.

from libcpp.memory cimport shared_ptr

from cython.operator cimport dereference

cdef extern from "mystruct.h" nogil:

cdef cppclass mystruct:

int a, b, c, d, e, f, g, h, i, j, k, l, m

ctypedef vector[v] mystruct_list

cdef class MyStruct:

cdef shared_ptr[mystruct] ptr

def __cinit__(MyStruct self):

self.ptr.reset(new mystruct)

property a:

def __get__(MyStruct self):

return dereference(self.ptr).a

def __set__(MyStruct self, int value):

dereference(self.ptr).a = value

cdef class MyStructList:

cdef mystruct_list c

cdef mystruct_list.iterator it

def __cinit__(MyStructList self):

pass

def __getitem__(MyStructList self, int index):

# How do return MyStruct without copying the underlying `mystruct`

pass

我看到许多可能的解决方法,但没有一个是非常令人满意的:

我可以初始化一个空的MyStruct,并在Cython中通过shared_ptr进行分配.然而,这将导致浪费一个初始化的结构,绝对没有理由.

MyStruct value

value.ptr = self.c.at(index)

return value

我也可以将现有mystruct中的数据复制到新的mystruct中.然而,这遭受类似的膨胀.

MyStruct value

dereference(value.ptr).a = dereference(self.c.at(index)).a

return value

我还可以为每个__cinit__方法公开一个init = True标志,如果C对象已经存在(当init为False时),它将阻止在内部重建对象.但是,这可能会导致灾难性问题,因为它会暴露给Python API并允许取消引用null或未初始化的指针.

def __cinit__(MyStruct self, bint init=True):

if init:

self.ptr.reset(new mystruct)

我也可以使用暴露于Python的构造函数(它将重置self.ptr)重载__init__,但如果从Python层使用__new__,这将有危险的内存安全性.

底线

我很想使用Cython,编译速度,语法糖和许多其他原因,而不是相当笨重的boost :: python.我现在正在看pybind11,它可能会解决编译速度问题,但我仍然希望使用Cython.

有没有什么办法可以在Cython中以惯用方式完成这么简单的任务?谢谢.

最后

以上就是柔弱鸵鸟为你收集整理的python转cython_python – 使用现有C对象初始化Cython对象的全部内容,希望文章能够帮你解决python转cython_python – 使用现有C对象初始化Cython对象所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部