Note: Everything said on this page applies only to extension types, defined with the cdef class statement. It doesn't apply to classes defined with the Python class statement, where the normal Python rules apply.
The __cinit__ method is where you should perform basic C-level initialisation of the object, including allocation of any C data structures that your object will own. You need to be careful what you do in the __cinit__ method, because the object may not yet be a valid Python object when it is called. Therefore, you must not invoke any Python operations which might touch the object; in particular, do not try to call any of its methods.
By the time your __cinit__ method is called, memory has been allocated for the object
and any C attributes it has have been initialised to 0 or null. (Any Python
attributes have also been initialised to None, but you probably shouldn't
rely on that.) Your __cinit__ method is guaranteed to be called exactly
once.
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.
If you need to pass a modified argument list to the base type, you will have
to do the relevant part of the initialisation in the __init__ method
instead (where the normal rules for calling inherited methods apply).
Any initialisation which cannot safely be done in the __cinit__ method should be done in the __init__ method. By the time __init__ is called, the object is a fully valid Python object and all operations are safe. Under some circumstances it is possible for __init__ to be called more than once or not to be called at all, so your other methods should be designed to be robust in such situations.
Any arguments passed to the constructor will be passed to both the __cinit__ method and the __init__ method. 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. Otherwise, any Python subclass which has an __init__ with a different signature will have to override __new__ as well as __init__, which the writer of a Python class wouldn't expect to have to do.
You need to be careful what you do in a __dealloc__ method. By the time your __dealloc__ method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don't call any other methods of the object or do anything which might cause the object to be resurrected. It's best if you stick to just deallocating C data.
You don't need to worry about deallocating Python attributes of your object,
because that will be done for you by Pyrex after your __dealloc__
method returns.
Note: There is no __del__ method for extension types.
This means that you can't rely on the first parameter of these methods being "self", and you should test the types of both operands before deciding what to do. If you can't handle the combination of types you've been given, you should return NotImplemented.
This also applies to the in-place arithmetic method __ipow__. It doesn't apply to any of the other in-place methods (__iadd__, etc.) which always take self as the first argument.
<
|
0 |
==
|
2 |
>
|
4 | ||
<=
|
1 |
!=
|
3 |
>=
|
5 |
You don't have to declare your method as taking these parameter types.
If you declare different types, conversions will be performed as necessary.
Name | Parameters | Return type | Description |
General | |||
__cinit__ | self, ... | Basic initialisation (no direct Python equivalent) | |
__init__ | self, ... | Further initialisation | |
__dealloc__ | self | Basic deallocation (no direct Python equivalent) | |
__cmp__ | x, y | int | 3-way comparison |
__richcmp__ | x, y, int op | object | Rich comparison (no direct Python equivalent) |
__str__ | self | object | str(self) |
__repr__ | self | object | repr(self) |
__hash__ | self | int | Hash function |
__call__ | self, ... | object | self(...) |
__iter__ | self | object | Return iterator for sequence |
__getattr__ | self, name | object | Get attribute |
__setattr__ | self, name, val | Set attribute | |
__delattr__ | self, name | Delete attribute | |
Arithmetic operators | |||
__add__ | x, y | object | binary + operator |
__sub__ | x, y | object | binary - operator |
__mul__ | x, y | object | * operator |
__div__ | x, y | object | / operator for old-style division |
__floordiv__ | x, y | object | // operator |
__truediv__ | x, y | object | / operator for new-style division |
__mod__ | x, y | object | % operator |
__divmod__ | x, y | object | combined div and mod |
__pow__ | x, y, z | object | ** operator or pow(x, y, z) |
__neg__ | self | object | unary - operator |
__pos__ | self | object | unary + operator |
__abs__ | self | object | absolute value |
__nonzero__ | self | int | convert to boolean |
__invert__ | self | object | ~ operator |
__lshift__ | x, y | object | << operator |
__rshift__ | x, y | object | >> operator |
__and__ | x, y | object | & operator |
__or__ | x, y | object | | operator |
__xor__ | x, y | object | ^ operator |
Numeric conversions | |||
__int__ | self | object | Convert to integer |
__long__ | self | object | Convert to long integer |
__float__ | self | object | Convert to float |
__oct__ | self | object | Convert to octal |
__hex__ | self | object | Convert to hexadecimal |
__index__ (2.5+ only) | self | object | Convert to sequence index |
In-place arithmetic operators | |||
__iadd__ | self, x | object | += operator |
__isub__ | self, x | object | -= operator |
__imul__ | self, x | object | *= operator |
__idiv__ | self, x | object | /= operator for old-style division |
__ifloordiv__ | self, x | object | //= operator |
__itruediv__ | self, x | object | /= operator for new-style division |
__imod__ | self, x | object | %= operator |
__ipow__ | x, y, z | object | **= operator |
__ilshift__ | self, x | object | <<= operator |
__irshift__ | self, x | object | >>= operator |
__iand__ | self, x | object | &= operator |
__ior__ | self, x | object | |= operator |
__ixor__ | self, x | object | ^= operator |
Sequences and mappings | |||
__len__ | self | int | len(self) |
__getitem__ | self, x | object | self[x] |
__setitem__ | self, x, y | self[x] = y | |
__delitem__ | self, x | del self[x] | |
__getslice__ | self, Py_ssize_t i, Py_ssize_t j | object | self[i:j] |
__setslice__ | self, Py_ssize_t i, Py_ssize_t j, x | self[i:j] = x | |
__delslice__ | self, Py_ssize_t i, Py_ssize_t j | del self[i:j] | |
__contains__ | self, x | int | x in self |
Iterators | |||
__next__ | self | object | Get next item (called next in Python) |
Buffer interface (no Python equivalents - see note 1) | |||
__getreadbuffer__ | self, int i, void **p | ||
__getwritebuffer__ | self, int i, void **p | ||
__getsegcount__ | self, int *p | ||
__getcharbuffer__ | self, int i, char **p | ||
Descriptor objects (see note 2) | |||
__get__ | self, instance, class | object | Get value of attribute |
__set__ | self, instance, value | Set value of attribute | |
__delete__ | self, instance | Delete attribute |
Note 1: The buffer interface is intended for use by C code and is not directly accessible from Python. It is described in the Python/C API Reference Manual under sections 6.6 and 10.6.
Note 2: Descriptor objects are part of the support mechanism for new-style Python classes. See the discussion of descriptors in the Python documentation. See also PEP 252, "Making Types Look More Like Classes", and PEP 253, "Subtyping Built-In Types".