2011-10-06 87 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中的变量