Google


Special Methods of Extension Types

This page describes the special methods currently supported by Pyrex extension types. A complete list of all the special methods appears in the table at the bottom. Some of these methods behave differently from their Python counterparts or have no direct Python counterparts, and require special mention.

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.

Initialisation methods: __new__ and __init__

There are two methods concerned with initialising the object.

The __new__ 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 __new__ 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.

Unlike the corresponding method in Python, your __new__ method is not responsible for creating the object. By the time your __new__ 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 __new__ method is guaranteed to be called exactly once.

Note that the first parameter of the __new__ method is the object to be initialised, not the class of the object as it is in Python.

Any initialisation which cannot safely be done in the __new__ 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.

Deallocation method: __dealloc__

Pyrex extension types do not have a __del__ method. Instead, they have a __dealloc__ method, which should perform the inverse of the __new__ method. Any C data structures that you allocated in your __new__ method should be freed in your __dealloc__ method.

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.

Arithmetic methods

Arithmetic operator methods, such as __add__, behave differently from their Python counterparts. There are no separate "reversed" versions of these methods (__radd__, etc.) Instead, if the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order.

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.

Rich comparisons

There are no separate methods for the individual rich comparison operations (__eq__, __le__, etc.) Instead there is a single method __richcmp__ which takes an integer indicating which operation is to be performed, as follows:
       
      <
      0
      ==
      2
      >
      4
      <=
      1
      !=
      3
      >=
      5

Special Method Table

This table lists all of the special methods together with their parameter and return types. A parameter named self is of the type the method belongs to. Other untyped parameters are generic Python objects.

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
__new__ 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
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, int i, int j object self[i:j]
__setslice__ self, int i, int j, x   self[i:j] = x
__delslice__ self, int i, int 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  (no Python equivalents - see note 2)
__get__ self, x, y object  
__set__ self, x, y object  

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, and are not officially documented yet. The only information currently available is to be found in PEP 252, "Making Types Look More Like Classes", and PEP 253, "Subtyping Built-In Types".