python extension_Python C Extension

C 扩展

什么情况下扩展Python 没有的额外功能

改善性能瓶颈

隐藏专有代码,当然也可以用PYC

什么情况不该扩展必须编写C代码

需要理解C与PYTHON之间的数据传递

需要手动的管理引用

示例

创建C代码

上干货 exten_c.c

#include

#include

#include

int fac(int n)

{

if (n<2) return(1);

return n * fac(n-1);

}

char *reserve(char *s)

{

register char t,

*p = s,

*q = (s + strlen(s) - 1);

while(p < q)

{

t = *p;

*p++ = *q;

*q-- = t;

}

return s;

}

void main()

{

char s[BUFSIZ];

char *w = "abcdefg";

printf("4!=%dn", fac(4));

strcpy(s, w);

printf("Reserve string %s to %sn", w, reserve(s));

}Make sure the c code could be right and accessiable and run sucessfully.

根据样板编写封装代码

python 与 C之间是通过一套C的库来完成相互之间的数据传递的。

其目录为: /usr/include/python[23].X/, 可以得到所有所需的函数

m distutils.core import setup, Extension

MOD=”extest”

setup(name=MOD, ext_modules=[Extension(MOD, sources=[‘exten_c.c’])])

封装后的代码为:#include

#include

#include

#include

int fac(int n)

{

if (n<2) return(1);

return n * fac(n-1);

}

char *reserve(char *s)

{

register char t,

*p = s,

*q = (s + strlen(s) - 1);

while(p < q)

{

t = *p;

*p++ = *q;

*q-- = t;

}

return s;

}

// 必须用static PyObject 来声明自己的函数

//必须使用 modulename_functionname 的格式定义函数

static PyObject *

extest_fac(PyObject *self, PyObject *args) {

int res; //parse result

int num; // fac parameter

PyObject *retval; //return value

res = PyArg_ParseTuple(args, "i", &num);

//获取python传进来的参数,并转化成C可以使用的类型

// 具体python的数据类型与C的数据类型对应关系,需要参照对照表

if (!res) {

return NULL;

}

res = fac(num); //执行真正的C函数

retval = (PyObject*)Py_BuildValue("i", res);

// 转换C的结果成python可以识别的类型

return retval;

}

static PyObject *

extest_rev1(PyObject *self, PyObject *args) {

char *orig_str;

char *dupe_str;

PyObject *retval; //return value

if (!PyArg_ParseTuple(args, "s", &orig_str)) return NULL;

retval = (PyObject*)Py_BuildValue("ss", orig_str, dupe_str=reverse(strdup(orig_str)));

free(dupe_str);

return retval;

}

//必须使用PyMethodDef去声明,

static PyMethodDef extestMethods[] = {

{ "fac", extest_fac, METH_VARARGS }, // {python中的函数名称, 对应的封装函数,返回的值}

{ "rev1", extest_rev1, METH_VARARGS },

{ NULL, NULL},

};

//python2.7可以编译成功, python3需要更改

PyMODINIT_FUNC initextest(void) {

Py_InitModule("extest", extestMethods);// {python module的名称,对应的module方法列表}

}

创建安装脚本

#!/usr/bin/env python

from distutils.core import setup, Extension

MOD="extest"

setup(name=MOD, ext_modules=[Extension(MOD, sources=['exten_c.c'])])

编译与安装

python setup build

python setup install

使用

#> python

>>> import extest

>>>dir(extest)

['__doc__', '__file__', '__name__', '__package__', 'fac', 'rev2']

>>>extest.fac(4)

24

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值