2016-10-21 69 views
1

我有一個C++類,它有一個返回結構向量的方法。在我當前的cython實現中,結構最終成爲字典,這是可以的,但不是最好的,我想以python對象的形式接收結構。cython將struct結構作爲對象

我目前的設置看起來像這樣。

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類型`並獲得有意義的結果。

現在我能看到的唯一的解決方案來自於使用本answer__dict__.update部分和包裝由self.thisptr.myclass_function()莫名其妙地返回的列表產生我的類的列表,每個得到__dict__.update治療。但有人會認爲,這樣做必須有更優雅和內置的循環方式。有任何想法嗎?

回答

1

的Structs比字典更低水平的數據類型,所以你不能使用它們,以便靈活地,只要你想,但你總是可以寫你自己的結構或用神奇方法結構的載體包裝就像一個__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__。  

+0

您的解決方案將原始字典存儲在一個對象中,該對象基本上像字典一樣工作,因爲__getitem__實現'[]'類型的調用。這將解決能夠檢查類型的問題,但並不真正使它成爲類似C的結構。 – fbence