[Pyrex] cdef'd classes initialization
Daniele Varrazzo
daniele.varrazzo at gmail.com
Tue Aug 8 16:33:22 UTC 2006
Hello,
i wrote some Pyrex classes to wrap C structures. Usually such classes
are responsible for the wrapped structure, and properly allocate them on
the heap and initialize on __init__ and free on __dealloc__. This is the
normal behaviour for all the instances directly created by a Python program.
Inside Pyrex, i don't always want such behavior. For example i have some
composite structures: the component is accessed from the composing
structure using a property. When the property __get__ is invoked, i
create from Pyrex a new instance to wrap the component structure. But
this instance doesn't own the wrapped structure: on __dealloc__ it must
not free() anything.
I don't like the way i implemented this mechanism: any such object has a
constructor:
def __init__(self, viewer=False):
if not viewer:
# allocation and initialization
else:
# other required things
but this constructor _must_ be called with default viewer=False from
Python: the case viewer=True is reserved for internal usage.
Furthermore viewers initialization is not complete: in the viewer case,
the structure pointer can't be set through a Python call (it's a void
*), so a property getter usually involves an idiom such as:
cdef MeasFileHeader rv
rv = MeasFileHeader(viewer=1)
rv.setStruct(&md.measFileHeader)
return rv
"More furthermore", this mechanism involves a Python call from C, with
the related Python call overhead (a dict and a tuple must be created, etc.)
So the question: is it possible to initialize a cdef'd class without
using the Python def'd __init__ method? If so i could create a factory
function (or a protected init method) implementing the "# other required
things" case above. I'd like to do:
def __init__(self): # to be called by Python
self.init_owner()
cdef init_owner(self): # to be called by Pyrex
# allocation and initialization
cdef init_viewer(self, void *s): # for Pyrex getters
# other required things
self.setStruct(s)
Can an instance be created by Pyrex without the __init__ call but with
an init_owner() or init_viewer() call instead? Or also without any call
at all? - i'd write proper (Pyrex) factory functions to be invoked to
create a new object instance.
Daniele
More information about the Pyrex
mailing list