开发者

Cython use of cinit()

I have:

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

when i call the DerClass in cyhton 开发者_如何学Pythonhappen that the construcor of the BaseClass is called automatically,what it has to print is:

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

but it does not,it crash ones that i call the DerClass('Ciao'). why does happen so and how can i avoid calling the cinit of BaseClass. Thank you!


The above answer may not pose quite the best solution. Reading the section "Initialisation methods: __cinit__() and __init__()" of the link above gives this information:

If your extension type has a base type, the __cinit__() method of the base type is automatically called before your __cinit__() method is called; you cannot explicitly call the inherited __cinit__() method.

and

If you anticipate subclassing your extension type in Python, you may find it useful to give the __cinit__() method * and ** arguments so that it can accept and ignore extra arguments.

So my solution would be to just replace the arguments of __cinit()__ in BaseClass so that a variable number of arguments can be passed to any derived class:

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

See here for an explanation of the *args variable in python


Well, you are right that you should see the cinit method called on your parent class. It says so right here in the docs.

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

Here is what I tried using:

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

It compiled but it gave me this error when I tried to run it:

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$

So I changed BaseClass.cinit to also take the "int n" parameter that DerClass.cinit does:

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

And now it seems to work fine:

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

Here is my runner.py file:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜