1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
.. _pxd_files:
pxd files
=========
In addition to the ``.pyx`` source files, Cython uses ``.pxd`` files
which work like C header files -- they contain Cython declarations
(and sometimes code sections) which are only meant for inclusion by
Cython modules. A ``pxd`` file is imported into a ``pyx`` module by
using the ``cimport`` keyword.
``pxd`` files have many use-cases:
1. They can be used for sharing external C declarations.
2. They can contain functions which are well suited for inlining by
the C compiler. Such functions should be marked ``inline``, example::
cdef inline int int_min(int a, int b):
return b if b < a else a
3. When accompanying an equally named ``pyx`` file, they
provide a Cython interface to the Cython module so that other
Cython modules can communicate with it using a more efficient
protocol than the Python one.
In our integration example, we might break it up into ``pxd`` files like this:
1. Add a ``cmath.pxd`` function which defines the C functions available from
the C ``math.h`` header file, like ``sin``. Then one would simply do
``from cmath cimport sin`` in ``integrate.pyx``.
2. Add a ``integrate.pxd`` so that other modules written in Cython
can define fast custom functions to integrate::
cdef class Function:
cpdef evaluate(self, double x)
cpdef integrate(Function f, double a,
double b, int N)
Note that if you have a cdef class with attributes, the attributes must
be declared in the class declaration ``pxd`` file (if you use one), not
the ``pyx`` file. The compiler will tell you about this.
__init__.pxd
^^^^^^^^^^^^
Cython also supports ``__init__.pxd`` files for declarations in package's
namespaces, similar to ``__init__.py`` files in Python.
Continuing the integration example, we could package the module as follows:
1. Place the module files in a directory tree as one usually would for
Python:
.. code-block:: text
CyIntegration/
├── __init__.pyx
├── __init__.pxd
├── integrate.pyx
└── integrate.pxd
2. In ``__init__.pxd``, use ``cimport`` for any declarations that one
would want to be available from the package's main namespace::
from CyIntegration cimport integrate
Other modules would then be able to use ``cimport`` on the package in
order to recursively gain faster, Cython access to the entire package
and the data declared in its modules::
cimport CyIntegration
cpdef do_integration(CyIntegration.integrate.Function f):
return CyIntegration.integrate.integrate(f, 0., 2., 1)
|