2012-06-07 99 views
3

是否有一種標準化(或普遍接受的方式)來解決在包裝C++類時無法在cython中重載__cinit__方法的問題?Cython和重載的C++構造函數

有可能讓__cinit__帶*參數和** kwargs來包含參數,並在__cinit__範圍內選擇按照某種模式生成C++實例的方式。然而,這種方法有併發症:

  • 試圖從參數識別正確的構造,除非參數被命名並作爲kwargs這可能會成爲用戶繁瑣的傳遞可能是在某些情況下的危險。
  • 當參數未被其類型在__cinit__參數列表中調用時,它們作爲Python對象傳遞。在我的工作案例中,參數是C++類的Python包裝,並試圖檢索這些實例「thisptr」是魔鬼的任務,當它們作爲來自* args或** kwargs的Python對象傳遞時。
  • 使用一系列if ... elif ... else case從參數組合中選擇C++構造函數的暗含需求最終變得相當混亂。

所以必須有更好的方法。一種方法可能是使用classmethod方法(例如,參見:classmethod to overload __init__ behavior in Python)。儘管如此,據我所知(如果我錯了,請糾正我),classmethod意味着調用名稱與類名不同的方法,這與C++僅使用一個類名構造實例的方式並不相像。

對此的任何想法?

回答

2

就個人而言,我會使用classmethods。

WrapperClass.fromSpambar(spambar) 

這並不是說puzzlin 恕我直言。如果你不能在C++中重載函數,你也需要回退到這種方法。

如果您可以接受一些重要的初始化操作,您可以實現一種方法來通過定義「模式」或類似方法來識別構造函數的調用方式。即args和kwargs的正則表達式。 ;)

我沒有看到從Python對象獲取thisptr的問題。

cdef WrapperClass wrpclsi 
if isinstance(instance, WrapperClass): 
    wrpclsi = instance 
else: 
    raise TypeError('expected instance of WrapperClass.') 

cdef WrappedClassFromCpp* thisptr = wrpclsi.thisptr 
+0

非常感謝Niklas,是的,看起來這樣做的方法將使用類方法,這也會使得對於參數類型的特定組合的處理更安全。正則表達式可能會和類方法結合使用(例如,如果有意義的話,選擇一個給定類型方法構造函數的組合)。 –

+0

關於thisptr部分...是的,我認爲這一點需要澄清我想說的內容。我的意思是聲明像 'def __cinit __(self,PyKlass klass)' 在'__cinit__'範圍內調用'klass.thisptr'沒有問題。然而,聲明: 'def __cinit(self,* args)' 假設在args [0]中有一個PyKlass實例,調用'args [0] .thisptr'會給麻煩,即使args [0]是一個PyClass類型的實例。 事實證明,這並不是什麼大問題,只需在'__cinit__'中投射即可解決,例如: 'klass = args [0]' –

+0

嗨tachys。我實際上並沒有談論真正的正則表達式,只是一個與可比機制相配的東西,但匹配* args *和* kwargs *。函數將傳遞的參數映射到它接受的參數上的方式相同,您可以處理* args *和* kwargs *,但允許多個調用約定。但是,這將涉及大量減速的處理。我可能會在第二天寫一些示例代碼。 –