I'm a Matlab and C++ user, and have recently discovered python (spyder) as a possible replacement for both. One of the main benefits I thought python had was the ability to work in interpreter mode, and then seamlessly translate it into fast compiled code once I'm satisfied with the result. The interpreted environment is great for prototyping, analyzing data while stopped at a breakpoint, throwing plots and images all around, etc.
I started looking into Cython, and I don't fully understand the programming flow. Lets say you have a .py code you'd like to speed up - Do you have to write a .pyx file from scratch? Can you run a .pyx file in interpreted mode as if it were a regular .py file (before compiling)? How do you debug the code in a .pyx file?
Cython code must, unlike Python, be compiled. This happens in two stages: A .pyx file is compiled by Cython to a .c file, containing the code of a Python extension module. The .c file is compiled by a C compiler to a .so file (or .pyd on Windows) which can be import-ed directly into a Python session.
Running the output of the CPython interpreter in a CPython virtual machine Compilation takes place when CPython compiles the source code (.py file) to generate the CPython bytecode (.pyc file). The CPython bytecode (.pyc file) is then interpreted using a CPython interpreter, and the output runs in a CPython virtual machine.
Cython code must, unlike Python, be compiled. This happens in two stages: A .pyx file is compiled by Cython to a .c file, containing the code of a Python extension module. The .c file is compiled by a C compiler to a .so file (or .pyd on Windows) which can be import -ed directly into a Python session. Distutils or setuptools take care of this part.
Compilers have this extra step of translating before executing, while interpreters run the code directly. A great example is when interpreters run Python code. While these two techniques are similar in what they are trying to do (get programs to run), how they go about it is extremely different. One key difference is in terms of performance.
I don't have too much experience with Cython, but judging from this entry in their documentation, the recommended workflow is to have a setup.py
file with the following lines:
from distutils.core import setup
from Cython.Build import cythonize
setup(name='Hello world app', ext_modules=cythonize("hello.pyx"))
Here hello.pyx
is just an example file, you will have to replace the string to reference your Python script.
Afterwards you will be able to call
python setup.py build_ext --inplace
which will compile your code and leave you with a new file. Now, as long as that file is in the same directory, you can easily import what you defined in your file, just like with any other module. E.g., suppose you compiled a file hello.pyx
with the function f
, you could write:
from hello import f
and then proceed to use f
.
Now, regarding your other questions. .pyx
seems to just indicate, that this should be Cython code, there is no real difference. Using the method with a setup.py
script as described above, you could also reference a file with the ending .py
. However, Python won't allow you to import from .pyx
files, only from the files created after compiling.
As to how you would debug code in a .pyx
file, I don't have enough information on that, though you could probably just debug the non-compiled file like a .py
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With