Reputation: 2153
I have a c++ class, that has a method which returns a vector of structs. In my current cython implementation the structs end up as dictionaries, which is ok, but not the best, I'd like to receive the structs as python objects.
My current setup looks like this.
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()
In this case calling myclass.myclass_function()
from python will give me a list of dictionaries, each having the key 'mystruct_property', which is functional, but a) it would be much better to be able to call it as a property
.mystruct_propertyand also would be nice to be able to call a
type` and get a meaningful result.
Right now the only solution I can see comes from using the __dict__.update
part of this answer and wrapping the list returned byself.thisptr.myclass_function()
somehow to produce a list of my class, each getting the __dict__.update
treatment. But one would think that there must be a more elegant and built-into-cython way of doing this. Any ideas?
Upvotes: 1
Views: 1086
Reputation: 1957
Structs is more low level datatype than dictionaries, so you can't use them so flexibly as you want, but you can always write your own wrapper for structs or vector of structs with magic methods like a __getattribute__
, __setattr__
which can take any access to items. This will looks like a struct with .
operator to get any field.
Something like this:
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())
Isn't it?
Also if you not sure about depth of sturcts\vectors (structs of structs, vectors of vectors of structs, etc), you can create your own functions to recursive conversion your structs to dictionaries with .
-access and lists.
But think any conversions is not good idea. __getattribute__
-accessing is more slow operation than native __getitem__
.
Upvotes: 1