cython使用cinit()

Ale*_* Vl 7 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__()"
               #...
Run Code Online (Sandbox Code Playgroud)

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

       BaseClass __cinit__()
       DerClass __cinit__()
       DerClass __dealloc__()
       BaseClass __dealloc__()
Run Code Online (Sandbox Code Playgroud)

但事实并非如此,我称之为DerClass('Ciao').为什么发生,所以,我怎么能避免调用CINIT的BaseClass的.谢谢!

小智 5

上面的答案可能不是最好的解决方案。阅读上面链接的“初始化方法:__cinit__() 和 __init__()”部分提供了以下信息:

如果你的扩展类型有基类型,在__cinit__()调用你的__cinit__()方法之前会自动调用基类型的方法;您不能显式调用继承的__cinit__()方法。

如果您希望在 Python 中对您的扩展类型进行子类化,您可能会发现为__cinit__()方法提供 * 和 ** 参数很有用,以便它可以接受和忽略额外的参数。

所以我的解决方案是只替换__cinit()__in的参数,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__()"
        #...
Run Code Online (Sandbox Code Playgroud)

请参阅此处了解*argspython中的变量的解释


Mik*_*ord 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__()"
       #...
Run Code Online (Sandbox Code Playgroud)

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

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$
Run Code Online (Sandbox Code Playgroud)

所以我改变了BaseClass。cinit还采用 DerClass.cinit 的“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__()"
       #...
Run Code Online (Sandbox Code Playgroud)

现在它似乎工作正常:

mike@computer:~/testing$ python runner.py 
BaseClass __cinit__()
DerClass __cinit__()
DerClass __dealloc__()
BaseClass __dealloc__()
mike@computer:~/testing$ 
Run Code Online (Sandbox Code Playgroud)

这是我的 runner.py 文件:

from test import *
if __name__ == "__main__":
    DerClass('Ciao', 1)
Run Code Online (Sandbox Code Playgroud)