Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Hardware and software Environment
- Ubuntu 18.04 64 – bit
- Anaconda with python 3.6
- Cython 0.27.3
Cython profile
Cython is a compiler that allows Python scripts to support EXTENSIONS to the C language. Cython is a superset of Python that converts.pyx scripts encoded in both Python and C into C code. Mainly used to optimize Python script performance or Python calling C function libraries. Due to Python’s inherent poor performance, extending Python with C has become a common way to improve Python performance. This article focuses on using Cython to compile Python code into a dynamically linked library in C, commonly known as SO.
Cython installation
Install first using PIP
pip install cython
Copy the code
Preparing the Python module
Our default library installation directory in Anaconda
CD/home/xugaoxiang anaconda3 / lib/python3.6 / site - packages mkdir djstava CD djstava touch set py test. PyCopy the code
Create files __init__.py and test.py
Edit the contents of the test.py file as
def test():
'''
Just an example.
'''
print('Hello Cython.')
Copy the code
Next test whether the module created below can be imported and whether the methods in it work properly. This can be done in Python or ipython
Xugaoxiang @ ubuntu: ~ / anaconda3 / lib/python3.6 / site - $python packages/djstava 3.6.4 radar echoes captured | Anaconda custom | (64 - bit) (Default, Jan 16 2018, 18:10:19) [GCC 7.2.0] on Linux Type "help", "copyright", "credits" or "license" for more information. >>> import djstava.test >>> djstava.test.test <function test at 0x7ff35f135598> >>> djstava.test.test() Hello Cython.Copy the code
OK, the test module is now created
Compile into the SO library
Next, use Cython to convert test.py to test.c and compile to the dynamic link library so
CD/home/xugaoxiang anaconda3 / lib/python3.6 / site - packages/djstava cython test. PyCopy the code
Generate the test.c file and use the following command
GCC -fpic - c - I/home/xugaoxiang/anaconda3 / include/python3.6 m test. CCopy the code
Generate the target file that is. O file, and finally link into a dynamic library
gcc -shared test.o -o test.so
Copy the code
At this point, the dynamic library is formally generated.
Test so
Ipython this time we use to test, first advanced to the directory/home/xugaoxiang anaconda3 / lib/python3.6 / site – packages/djstava, will test. Py files deleted, so as not to interfere
Xugaoxiang @ ubuntu: ~ / anaconda3 / lib/python3.6 / site - packages/djstava $ipython Python 3.6.4 radar echoes captured | Anaconda custom | (64 - bit) (default, Jan 16 2018, 18:10:19) Type 'copyright', 'Credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive python. Type '? ' for help. In [1]: import djstava.test In [2]: djstava.test.test Out[2]: <cyfunction test at 0x7f90945bbc80> In [3]: djstava.test.test() Hello Cython.Copy the code
The method called to the test module and the result of execution is exactly the same as test.py
In addition, how about in python to call C language dynamic link library, you can refer to previous articles xugaoxiang.com/2019/12/08/…
Used in conjunction with setup.py
If you still don’t understand the setup. Py, please click xugaoxiang.com/2019/12/08/… . In order not to conflict with the above project, we will create a new directory /home/xugaoxiang/test and create a file called test.pyx, which allows C and Python to be mixed
def test():
'''
Just an example.
'''
print('Hello Cython.')
Copy the code
Write the setup.py file
from distutils.core import setup
from Cython.Build import cythonize
setup(
name='Test pyx',
ext_modules=cythonize('test.pyx')
)
Copy the code
After editing, run the python setup.py build command to start the installation
xugaoxiang@ubuntu:~/test$ python setup.py build Compiling test.pyx because it changed. [1/1] Cythonizing test.pyx Build_ext building 'test' extension Creating build/temp. Linux-x86_64-3.6gcc -pthread -B /home/xugaoxiang/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall - Wstrict - as the -fpic - I/home/xugaoxiang/anaconda3 / include/python3.6 m - c test. C - o Linux-x86_64-3.6 /test.o creating build/lib.linux-x86_64-3.6 GCC - pthread-shared-b /home/xugaoxiang/anaconda3/compiler_compat -L/home/xugaoxiang/anaconda3/lib -Wl,-rpath=/home/xugaoxiang/anaconda3/lib - Wl - no - as - men - Wl, -- sysroot = / build/temp. Linux - x86_64-3.6 / test. O - o Build/lib. Linux - x86_64-3.6 / test. The retaining - 36 m - x86_64 - Linux - gnu. SoCopy the code
The compiled file directory structure is as follows
xugaoxiang@ubuntu:~/test$ ls -R .: build setup.py test.c test.pyx ./build: Lib. Linux - x86_64-3.6 temp. Linux - x86_64-3.6 / build/lib. Linux - x86_64-3.6: Test. Retaining - 36 m - x86_64 - Linux - gnu. So. / build/temp. Linux - x86_64-3.6: test. OCopy the code
Notice that the test.c file has been generated, along with the.o and.so files under build. Create a new folder in the current directory, copy the so file from the previous step, and create a new __init__.py file with the contents of
from test import *
Copy the code
And then we start testing
Xugaoxiang @ ubuntu: ~ / test/test $ipython Python 3.6.4 radar echoes captured | Anaconda custom (64 - bit) | (default, Jan 16, 2018, 18:10:19) Type 'copyright', 'Credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive python. Type '? ' for help. In [1]: import test In [2]: test.test() Hello Cython.Copy the code
The resources
- cython.org/
- Docs.python.org/3/extending…
- Stackoverflow.com/questions/2…
- Cython. Readthedocs. IO/en/latest/s…