Python高级编程——编写扩展

Python扩展三种不同的实现方式:

一、编写纯C扩展。

  写过JNI的人很容易理解,纯C扩展就是利用Python/C API来扩展python应用。C/API的详细使用,请参见:  https://docs.python.org/3.6/c-api/

例子:

"""setup.py文件:用来告诉解释器我们的扩展是如何编译的
  扩展的构建过程可以通过Python的setup.py构建命令初始化,并且它会在程序包安装时自动执行
"""
from setuptools import setup, Extension
setup(
    name='fibonacci',
    ext_modules=[
        Extension('fibonacci', ['fibonacci.c']),
    ]
)

"""fibonacci.c文件"""

#Python.h把整个Python/C API以及编写扩展需要引入的一切包含进来
#include <Python.h>


long long fibonacci(unsigned int n) {
    if (n < 2) {
        return 1;
    } else {
        return fibonacci(n-2) + fibonacci(n-1);
    }
}

static PyObject* fibonacci_py(PyObject* self, PyObject* args) {
    PyObject *result = NULL;
    long n;
    if (PyArg_ParseTuple(args, "l", &n)) {
        result = Py_BuildValue("L", fibonacci((unsigned int)n));
    }
    return result;
}


static char fibonacci_docs[] =
    "fibonacci(n): Return nth Fibonacci sequence number "
    "computed recursively\n";


static PyMethodDef fibonacci_module_methods[] = {
    {"fibonacci", (PyCFunction)fibonacci_py,
     METH_VARARGS, fibonacci_docs},
    {NULL, NULL, 0, NULL}
};


static struct PyModuleDef fibonacci_module_definition = {
    PyModuleDef_HEAD_INIT,
    "fibonacci",
    "Extension module that provides fibonacci sequence function",
    -1,
    fibonacci_module_methods
};


PyMODINIT_FUNC PyInit_fibonacci(void) {
    Py_Initialize();
    return PyModule_Create(&fibonacci_module_definition);
}

 

二、使用Cython

Cython既是一个优化的静态编译器,也是一个Python的超集编程语言的名称。作为编译器,它可以使用Python/C API执行源到源的编译,把Python代码及其Cython方言编译为Python C扩展。它允许你结合Python和C的威力,而不需要手动处理Python/C API。

2.1 Cython作为源码编译器

setup.py脚本文件

from setuptools import setup
from Cython.Build import cythonize


setup(
    name='fibonacci',
    ext_modules=cythonize(['fibonacci.pyx'])
)

Cython源文件:fibonacci.pyx

"""Cython module that provides fibonacci sequence function"""

cdef long long fibonacci_cc(unsigned int n):
    if n < 2:
        return n
    else:
        return fibonacci_cc(n - 1) + fibonacci_cc(n - 2)


def fibonacci(unsigned int n):
    """ Return nth Fibonacci sequence number computed recursively
    """
    return fibonacci_cc(n)

使用以下命令启用可选的Cython依赖与编译器:

$ USE_CYTHON=1 pip install .[with-cython]

2.1 Cython作为一门语言

"""Python module that provides fibonacci sequence function"""


def fibonacci(n):
    """ Return nth Fibonacci sequence number computed recursively
    """
    if n < 2:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)
from setuptools import setup
from Cython.Build import cythonize


setup(
    name='fibonacci',
    ext_modules=cythonize(['fibonacci.py'])
)

相比于将Cython作为编译器,唯一真正改变是的fibonacci函数的签名。

三、使用Pyrex

     Pyrex 是一种专门设计用来编写 Python 扩展模块的语言。根据 Pyrex Web 站点的介绍,“它被设计用来在友好易用的高级 Python 世界和凌乱的低级 C 世界之间搭建一个桥梁。”虽然几乎所有的 Python 代码都可以作为有效的 Pyrex 代码使用,但是您可以在 Pyrex 代码中添加可选的静态类型声明,从而使得这些声明过的对象以 C 语言的速度运行。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章