2011-10-06 72 views
4

我:用Cython使用CINIT的()

 cdef class BaseClass(): 
      def __cinit__(self,char* name): 
       print "BaseClass __cinit__()" 
       #... 
      def __dealloc__(): 
       print "BaseClass __dealloc__()" 
       #... 
     cdef class DerClass(BaseClass): 
      def __cinit__(self,char* name,int n): 
       print "DerClass __cinit__()" 
       #... 
      def __dealloc__(): 
       print "DerClass __dealloc__()" 
       #... 

當我打電話DerClass在cyhton發生了BaseClass的的construcor被自動調用,它具有打印是:

 BaseClass __cinit__() 
     DerClass __cinit__() 
     DerClass __dealloc__() 
     BaseClass __dealloc__() 

但它沒有,它崩潰了,我稱之爲DerClass('Ciao')。 爲什麼會發生這種情況,我如何避免調用BaseClass的cinit。 謝謝!

回答

3

嗯,你是對的,你應該看到cinit方法調用你的父類。它在文檔中這麼說。

http://docs.cython.org/src/userguide/special_methods.html

這裏是我嘗試使用:

cdef class BaseClass: 
    def __cinit__(self,char* name): 
     print "BaseClass __cinit__()" 
     #... 
    def __dealloc__(self): 
     print "BaseClass __dealloc__()" 
     #... 
cdef class DerClass(BaseClass): 
    def __cinit__(self,char* name,int n): 
     print "DerClass __cinit__()" 
     #... 
    def __dealloc__(self): 
     print "DerClass __dealloc__()" 
     #... 

它編譯,但是當我試圖運行它,它給了我這個錯誤:

[email protected]:~/testing$ python runner.py 
DerClass __dealloc__() 
BaseClass __dealloc__() 
Traceback (most recent call last): 
    File "runner.py", line 4, in <module> 
    DerClass('Ciao', 1) 
    File "test.pyx", line 2, in test.BaseClass.__cinit__ (test.c:488) 
    def __cinit__(self,char* name): 
TypeError: __cinit__() takes exactly 1 positional argument (2 given) 
[email protected]:~/testing$ 

因此,我改變的BaseClass。 cinit也採用DerClass的「int n」參數。 CINIT做:

cdef class BaseClass: 
    def __cinit__(self, char * name, int n): 
     print "BaseClass __cinit__()" 
     #... 
    def __dealloc__(self): 
     print "BaseClass __dealloc__()" 
     #... 
cdef class DerClass(BaseClass): 
    def __cinit__(self,char* name,int n): 
     print "DerClass __cinit__()" 
     #... 
    def __dealloc__(self): 
     print "DerClass __dealloc__()" 
     #... 

而現在它似乎很好地工作:

[email protected]:~/testing$ python runner.py 
BaseClass __cinit__() 
DerClass __cinit__() 
DerClass __dealloc__() 
BaseClass __dealloc__() 
[email protected]:~/testing$ 

這裏是我的runner.py文件:

from test import * 
if __name__ == "__main__": 
    DerClass('Ciao', 1) 
2

以上回答可能不會造成相當最佳方案。讀取部「初始化方法:__cinit __()和__init __()」以上的鏈接的給出了這樣的信息:

如果擴展類型都有一個基本類型,基本類型的__cinit__()方法被自動之前稱爲你調用方法__cinit__();您不能顯式調用繼承的__cinit__()方法。

如果您預計子類在Python的擴展類型,你會發現它有用給予__cinit__()方法*和**參數,以便它可以接受,而忽略額外的參數。

所以我的解決辦法是隻需更換的__cinit()__的論據BaseClass,這樣的參數個數可變可以傳遞到任何派生類:

cdef class BaseClass: 
    def __cinit__(self, *argv): 
     print "BaseClass __cinit__()" 
     #... 
def __dealloc__(self): 
     print "BaseClass __dealloc__()" 
     #... 

cdef class DerClass(BaseClass): 
    def __cinit__(self,char* name, int n): 
     print "DerClass __cinit__()" 
     #... 
    def __dealloc__(self): 
     print "DerClass __dealloc__()" 
     #... 

*args的說明,請參見here python中的變量