我有一个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方式来做到这一点。有什么想法吗?
答案 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__
更慢。