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)
精彩评论