Cython using 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 DerClass in cyhton, it happens that the BaseClass constructor is called automatically, what it should print:

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

but itโ€™s not, it breaks down what I call DerClass ('Ciao'). why this happens, and how can I avoid calling cinit BaseClass. Thanks!

+4
source share
2 answers

Well, you're right that you should see the cinit method, which is called in its parent class. He says so right here in the documents.

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

Here is what I tried to use:

 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 parameter "int n", which is DerClass. 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__()" #... 

And now it works 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) 
+3
source

The above answer may not be the best solution. Reading the section โ€œInitialization Methods: __cinit __ () and __init __ ()โ€ in the link above gives the following information:

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

and

If you expect a subclassification of your type of extensions in Python, you might find it useful to give the arguments __cinit__() method * and ** so that it can accept and ignore additional arguments.

So my solution would be to simply replace the __cinit()__ arguments 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

+2
source

All Articles