This page describes the special methods currently supported by Cython 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.
Everything said on this page applies only to extension types, defined with the
statement. It doesn’t apply to classes defined with the Python
statement, where the normal Python rules apply.
Currently, docstrings are not fully supported in some special methods of extension types. You can place a docstring in the source to serve as a comment, but it won’t show up in the corresponding
attribute at run time. (This seems to be is a Python limitation – there’s nowhere in the
data structure to put such docstrings.)
There are two methods concerned with initialising the object.
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
method, because the object may not yet be fully valid Python object when it is called. Therefore, you should be careful invoking any Python operations which might touch the object; in particular, its methods.
By the time your
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
method is guaranteed to be called exactly once.
If your extension type has a base type, the
method of the base type is automatically called before your
method is called; you cannot explicitly call the inherited
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
method instead (where the normal rules for calling inherited methods apply).
Any initialisation which cannot safely be done in the
method should be done in the
method. By the time
is called, the object is a fully valid Python object and all operations are safe. Under some circumstances it is possible for
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
method. If you anticipate subclassing your extension type in Python, you may find it useful to give the
arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an
with a different signature will have to override
, which the writer of a Python class wouldn’t expect to have to do. Alternatively, as a convenience, if you declare your
method to take no arguments (other than self) it will simply ignore any extra arguments passed to the constructor without complaining about the signature mismatch.
All constructor arguments will be passed as Python objects. This implies that non-convertible C types such as pointers or C++ objects cannot be passed into the constructor from Cython code. If this is needed, use a factory function instead that handles the object initialisation. It often helps to directly call
in this function to bypass the call to the
见 从现有 C/C++ 指针实例化 范例。
The counterpart to the
method is the
method, which should perform the inverse of the
method. Any C data that you explicitly allocated (e.g. via malloc) in your
method should be freed in your
You need to be careful what you do in a
method. By the time your
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 Cython after your
When subclassing extension types, be aware that the
method of the superclass will always be called, even if it is overridden. This is in contrast to typical Python behavior where superclass methods will not be executed unless they are explicitly called by the subclass.
There is no
method for extension types.
Arithmetic operator methods, such as
, behave differently from their Python counterparts. There are no separate “reversed” versions of these methods (
, 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” or being the right type, 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
. It doesn’t apply to any of the other in-place methods (
, etc.) which always take
as the first argument.
There are two ways to implement comparison methods. Depending on the application, one way or the other may be better:
The first way uses the 6 Python
, etc. This is new since Cython 0.27 and works exactly as in plain Python classes.
The second way uses a single special method
. This implements all rich comparison operations in one method. The signature is
. The integer argument
indicates which operation is to be performed as shown in the table below:
These constants can be cimported from the
Extension types wishing to implement the iterator interface should define a method called
, not next. The Python system will automatically supply a next method which calls your
explicitly give your type a
method, or bad things could happen.
This table lists all of the special methods together with their parameter and return types. In the table below, a parameter name of self is used to indicate that the parameter has the type that the method belongs to. Other parameters with no type specified in the table 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.
|__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|
|__iter__||self||object||Return iterator for sequence|
|__getattr__||self, name||object||Get 属性|
|__getattribute__||self, name||object||Get attribute, unconditionally|
|__setattr__||self, name, val||Set 属性|
You can choose to either implement the standard Python special methods like
or the single special method
. Depending on the application, one way or the other may be better.
|__eq__||self, y||object||self == y|
self != y (falls back to
|__lt__||self, y||object||self < y|
|__gt__||self, y||object||self > y|
|__le__||self, y||object||self <= y|
|__ge__||self, y||object||self >= y|
|__richcmp__||self, y, int op||object||Joined rich comparison method for all of the above (no direct Python equivalent)|
|__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|
|__nonzero__||self||int||convert to boolean|
|__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|
|__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|
|__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|
|__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|
|__next__||self||object||Get next item (called next in Python)|
|__getbuffer__||self, Py_buffer *view , int flags|
|__releasebuffer__||self, Py_buffer *view|
|__getreadbuffer__||self, Py_ssize_t i, void **p|
|__getwritebuffer__||self, Py_ssize_t i, void **p|
|__getsegcount__||self, Py_ssize_t *p|
|__getcharbuffer__||self, Py_ssize_t i, char **p|
|__get__||self, instance, class||object||Get value of attribute|
|__set__||self, instance, value||Set value of attribute|
(1) The buffer interface was intended for use by C code and is not directly accessible from Python. It is described in the Python/C API Reference Manual of Python 2.x under sections 6.6 and 10.6. It was superseded by the new PEP 3118 buffer protocol in Python 2.6 and is no longer available in Python 3. For a how-to guide to the new API, see 实现缓冲协议 .