cython使用cinit()

时间:2011-10-06 13:54:01

标签: cython

我有:

      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__()"
               #...

当我在cyhton中调用DerClass时,会自动调用BaseClass的构造,它必须打印的是:

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

但它没有,它崩溃了我称之为DerClass('Ciao')。 为什么会这样,我怎么能避免调用BaseClass的 cinit 。 谢谢!

2 个答案:

答案 0 :(得分:4)

嗯,你应该看到你父类调用的 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__()"
       #...

它已编译但在我尝试运行时它给了我这个错误:

mike@computer:~/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)
mike@computer:~/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__()"
       #...

现在似乎工作正常:

mike@computer:~/testing$ python runner.py 
BaseClass __cinit__()
DerClass __cinit__()
DerClass __dealloc__()
BaseClass __dealloc__()
mike@computer:~/testing$ 

这是我的runner.py文件:

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

答案 1 :(得分:3)

上述答案可能不是最佳解决方案。阅读&#34;初始化方法:__cinit __()和__init __()&#34;上面的链接提供了这个信息:

  

如果您的扩展类型具有基本类型,则在调用__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__()"
        #...

有关python

*args变量的说明,请参阅here