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 語言的速度運行。

 

 

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