* Any arguments passed to the extension type's constructor, will be passed to both initialization methods.
* ``__cinit__()`` is where you should perform C-level initialization of the object
* This includes any allocation of C data structures.
* **Caution** is warranted as to what you do in this method.
* The object may not be fully valid Python object when it is called.
* Calling Python objects, including the extensions own methods, may be hazardous.
* By the time ``__cinit__()`` is called...
* Memory has been allocated for the object.
* All C-level attributes have been initialized to 0 or null.
* Python have been initialized to ``None``, but you can not rely on that for each occasion.
* This initialization method is guaranteed to be called exactly once.
* For Extensions types that inherit a base type:
* The ``__cinit__()`` method of the base type is automatically called before this one.
* The inherited ``__cinit__()`` method can not be called explicitly.
* Passing modified argument lists to the base type must be done through ``__init__()``.
* It may be wise to give the ``__cinit__()`` method both ``"*"`` and ``"**"`` arguments.
* Allows the method to accept or ignore additional arguments.
* Eliminates the need for a Python level sub-class, that changes the ``__init__()`` method's signature, to have to override both the ``__new__()`` and ``__init__()`` methods.
* If ``__cinit__()`` is declared to take no arguments except ``self``, it will ignore any extra arguments passed to the constructor without complaining about a signature mis-match
* ``__init__()`` is for higher-level initialization and is safer for Python access.
* By the time this method is called, the extension type is a fully valid Python object.
* All operations are safe.
* This method may sometimes be called more than once, or possibly not at all.
* Take this into consideration to make sure the design of your other methods are robust of this fact.
Finalization: ``__dealloc__()``
===============================
* This method is the counter-part to ``__cinit__()``.
* Any C-data that was explicitly allocated in the ``__cinit__()`` method should be freed here.
* Use caution in this method:
* The Python object to which this method belongs may not be completely intact at this point.
* Avoid invoking any Python operations that may touch the object.
* Don't call any of this object's methods.
* It's best to just deallocate C-data structures here.
* All Python attributes of your extension type object are deallocated by Cython after the ``__dealloc__()`` method returns.
Arithmetic Methods
==================
.. note:: Most of these methods behave differently than in Python
* There are not "reversed" versions of these methods... there is no __radd__() for instance.
* If the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order.
* Do not rely on the first parameter of these methods, being ``"self"`` or the right type.
* The types of both operands should be tested before deciding what to do.
* Return ``NotImplemented`` for unhandled, mis-matched operand types.
* The previously mentioned points..
* Also apply to 'in-place' method ``__ipow__()``.
* Do not apply to other 'in-place' methods like ``__iadd__()``, in that these always take ``self`` as the first argument.
Rich Comparisons
================
.. note:: There are no separate methods for individual rich comparison operations.
* A single special method called ``__richcmp__()`` replaces all the individual rich compare, special method types.
* ``__richcmp__()`` takes an integer argument, indicating which operation is to be performed as shown in the table below.
+-----+-----+
| < | 0 |
+-----+-----+
| == | 2 |
+-----+-----+
| > | 4 |
+-----+-----+
| <= | 1 |
+-----+-----+
| != | 3 |
+-----+-----+
| >= | 5 |
+-----+-----+
The ``__next__()`` Method
=========================
* Extension types used to expose an iterator interface should define a ``__next__()`` method.
* **Do not** explicitly supply a ``next()`` method, because Python does that for you automatically.
===========
===========
Subclassing
Subclassing
===========
===========
* An extension type may inherit from a built-in type or another extension type::
cdef class Parrot:
...
cdef class Norwegian(Parrot):
...
* A complete definition of the base type must be available to Cython
* If the base type is a built-in type, it must have been previously declared as an ``extern`` extension type.
* ``cimport`` can be used to import the base type, if the extern declared base type is in a ``.pxd`` definition file.
* In Cython, multiple inheritance is not permitted.. singlular inheritance only
* Cython extenstion types can also be sub-classed in Python.
* Here multiple inhertance is permissible as is normal for Python.
* Even multiple extension types may be inherited, but C-layout of all the base classes must be compatible.
====================
====================
Forward Declarations
Forward Declarations
====================
====================
* Extension types can be "forward-declared".
* This is necessary when two extension types refer to each other::
cdef class Shrubbery # forward declaration
cdef class Shrubber:
cdef Shrubbery work_in_progress
cdef class Shrubbery:
cdef Shrubber creator
* An extension type that has a base-class, requires that both forward-declarations be specified::
cdef class A(B)
...
cdef class A(B):
# attributes and methods
========================
========================
Extension Types and None
Extension Types and None
========================
========================
...
@@ -175,6 +341,16 @@ Extension Types and None
...
@@ -175,6 +341,16 @@ Extension Types and None
Weak Referencing
Weak Referencing
================
================
* By default, weak references are not supported.
* It can be enabled by declaring a C attribute of the ``object`` type called ``__weakref__()``::