python高性能之路:使用C/C++编写扩展

脚本语言通常使用c等静态语言编写扩展提升性能,下面使用cpp编写一个实现两数之和的python扩展函数html

完成案例代码参考:1drv.ms/u/s!AquRvPz…python

构建python环境

减小扩展开发对系统python的影响,建议使用venv建立一个新的python开发环境ios

virtualenv ~/develop/venvpy3
复制代码

操做效果以下 shell

-w482

使用命令source ~/develop/venvpy3/bin/activate激活便可api

建立扩展文件sumext.cpp

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…

定义函数为python扩展函数

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编译,效果参考以下

-w810

使用扩展

action.py

import sumext

sum=sumext.sum(1, 2)

print("Sum is :", sum)
复制代码

而后使用命令python action.py执行,执行效果以下:

-w336

能够看到扩展已经成功加载执行了

参考资料

  1. docs.python.org/3/extending…
  2. docs.python.org/3/extending…
  3. www.tutorialspoint.com/python/pyth…
  4. docs.python.org/3/c-api/arg…
相关文章
相关标签/搜索