cython wrap struct as object

时间:2016-10-21 21:38:27

标签: python struct cython

我有一个c ++类,它有一个返回结构向量的方法。在我目前的cython实现中,结构最终是字典,这是好的,但不是最好的,我希望将结构作为python对象接收。

我目前的设置是这样的。

cpp_mycode.pxd

from libcpp.vector cimport vector
cdef extern from "myheader.h":
    cdef struct mystruct:
         int mystruct_property

    cdef cppclass myclass:
         myclass()
         vector[mystruct] myclass_function()

mycode.pyx

cimport cpp_mycode

cdef class myclass:
    cdef cpp_mycode.myclass *thisptr
    def __cinit__(self):
         self.thisptr = new cpp_myclass.myclass()
    def __dealloc(self):
         if self.thisptr is not NULL:
              delf self.thisptr
    def myclass_function(self):
        return self.thisptr.myclass_function()

在这种情况下,从python调用myclass.myclass_function()会给我一个字典列表,每个字典都有密钥'mystruct_property', which is functional, but a) it would be much better to be able to call it as a property。mystruct_property and also would be nice to be able to call a type`并获得有意义的结果。

现在,我能看到的唯一解决方案来自于使用此answer__dict__.update部分,并以某种方式包装self.thisptr.myclass_function()返回的列表,以生成我的班级列表,每个都获得__dict__.update治疗。Class clsRecord public ID As Integer public fname As String public sName As String public grade As String 但人们会认为必须有更优雅和内置的cython方式来做到这一点。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

结构是比字典更低级别的数据类型,因此您不能如此灵活地使用它们,但是您总是可以使用像__getattribute__这样的魔术方法为结构或结构矢量编写自己的包装器, __setattr__可以访问任何项目。这看起来像一个带.运算符的结构来获取任何字段。

这样的事情:

class Wrapper():
    def __init__(self, in_dict):
         self.in_dict = in_dict

    def __getitem__(self, key):
         if key in self.in_dict:
              return self.in_dict[key]
         else:
              return super().__getitem__(key)

cdef class myclass:
    ...

    def myclass_function(self):
        return map(Wrapper, self.thisptr.myclass_function())

不是吗?

此外,如果你不确定sturcts \ vectors的深度(结构的结构,结构的向量的向量等),你可以创建自己的函数来递归转换你的结构到.的字典 - 访问和列表。

但是认为任何转换都不是好主意。 __getattribute__ - 访问操作比本机__getitem__更慢。