腳本語言通常使用c等靜態語言編寫擴展提升性能,下面使用cpp編寫一個實現兩數之和的python擴展函數html
完成案例代碼參考:1drv.ms/u/s!AquRvPz…python
減小擴展開發對系統python的影響,建議使用venv建立一個新的python開發環境ios
virtualenv ~/develop/venvpy3
複製代碼
操做效果以下 shell
使用命令source ~/develop/venvpy3/bin/activate
激活便可api
sumext.cpp函數
#include <iostream>
#include <stdio.h>
#include <Python.h>
using namespace std;
複製代碼
主要是引入依賴的Python.h文件頭便可,其它頭文件按需引入使用性能
static PyObject* sum(PyObject* Self, PyObject *args) {
int a, b, s;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
s = a + b;
return Py_BuildValue("i", s);
}
複製代碼
這個函數接受兩個int類型的參數,有一個int類型的返回值ui
PyArg_ParseTuple將python腳本中傳入的參數解析爲cpp本地數據類型,i表示解析爲int類型,兩個i:"ii"表示有兩個int類型的參數spa
支持解析的數據類型列表參考:docs.python.org/3/c-api/arg…code
Py_BuildValue用於將cpp本地數據類型轉爲python腳本數據類型,i表示將cpp中int類型轉爲python腳本變量
支持解析的數據類型列表參考:docs.python.org/2.0/ext/bui…
static PyMethodDef module_methods[] = {
{"sum", (PyCFunction) sum, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
複製代碼
static struct PyModuleDef sumext = {
PyModuleDef_HEAD_INIT,
"sumext",
"extension for add two number",
-1,
module_methods
};
複製代碼
PyMODINIT_FUNC PyInit_sumext(void) {
return PyModule_Create(&sumext);
}
PyMODINIT_FUNC PyInit_sum(void) {
return PyModule_Create(&sumext);
}
複製代碼
格式:PyInit_模塊名/函數名 做用:python加載模塊/模塊函數時的初始化函數,能夠在模塊/函數初始化函數中執行自定義鉤子邏輯,最後返回擴展信息sumext便可
setup.py:
from distutils.core import setup, Extension
setup(name='sumext', version='1.0', ext_modules=[Extension('sumext', ['sumext.cpp'])])
複製代碼
而後使用命令python setup.py install
編譯,效果參考以下
action.py
import sumext
sum=sumext.sum(1, 2)
print("Sum is :", sum)
複製代碼
而後使用命令python action.py
執行,執行效果以下:
能夠看到擴展已經成功加載執行了