失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 如何用Python写C扩展 – python – 前端 python网路爬虫代码

如何用Python写C扩展 – python – 前端 python网路爬虫代码

时间:2019-08-14 03:52:33

相关推荐

如何用Python写C扩展 – python – 前端 python网路爬虫代码

一般来说,Python扩展C,有三种方式,来实现加速,以下通过Python2.7,minw32 3.82.90,windows 7 进行说明。

一、ctypes

ctypes使用c函数,需要先将c编译成动态链接库,即.dll文件。

举个简单的栗子,c文件 examples.c:

#include <stdio.h>int show_me_the_money(int m) { printf(“Money is %d\n”, m); return m;}

编译成动态链接库:

mingw32-gcc examples.c -o examples.dll -shared

通过ctypes调用show_me_the_money这个函数:

#coding: utf-8

import ctypes

lib = ctypes.cdll.LoadLibrary(“examples.dll”)

lib.show_me_the_money(100)

结果是:

Money is 100

ctypes方式简单易用,只要动态库不涉及线程操作,交互的数据结构不复杂,特别是动态链接库已经有了,推荐使用。ctypes的详细细节可参考官方文档。

二、c extension方式

python c extension也是一种动态链接库,与一般的dll文件相比,它有两点不同

要实现一个PyMODINIT_FUNC函数,函数名称为 init模块名,比如你的模块名是pyTEST,那么这个函数名称就是 initpyTEST

文件后缀为.pyd

Enough talk, let’s fight!

pyTEST.c:

#include <Python.h>

#include <Windows.h>

static PyObject *

get_version(PyObject *self, PyObject *args)

{

return Py_BuildValue(“s”, “1.0”);

}

static PyMethodDef module_methods[] = {

{“get_version”, get_version, METH_VARARGS, “Get module version”},

{NULL,NULL, 0,NULL} /*Sentinel */

};

PyMODINIT_FUNC

initpyTEST(void)

{

PyObject *m;

m = Py_InitModule3(“pyTEST”, module_methods, “An example demostrates how python c extensions implement and work.”);

if (m == NULL) return;

}

编译:

mingw32-gcc -I./python/include -c pyTEST.c -o pyTEST.o

链接:

mingw32-gcc -shared -o pyTEST.pyd pyTEST.o -lpython27 -L./python/libs

测试脚本

#coding: utf-8

import pyTEST

print pyTEST.get_version()

执行结果

1.0

这种方式的c扩展有许多细节需要注意,比如引用计数的增减处理(Py_INCREF, Py_DECREF等宏的使用),处理错误就会造成内存泄漏或者非法内存访问,需要对borrowing references和new references有清晰的概念。

咱们来个栗子,做个测试,改一下get_version:

static PyObject *

get_version(PyObject *self, PyObject *args)

{

PyObject *ret = Py_BuildValue(“s”, “1.0”);

Py_DECREF(ret);

return ret;

}

再修改测试脚本:

#coding: utf-8

import pyTEST

import gc

v = pyTEST.get_version()

print v

gc.collect()

print “here, %s” % v

你就会发现Python挂了并提示:Fatal Python error:deletion of interned string failed。这其中有许多细节,比如返回的类型不同,结果也不同,大家可以自行测试。

三、SIP,Boost.Python, SWIG, Cython, Pybindgen

sip是Qt移植到python过程中开发的,wxWidget也有大量使用;cython一般多用于科学计算领域的加速。

这方面本人应用用的不多,就不在此误人子弟。期待高手们解答,分享经验。

如果觉得《如何用Python写C扩展 – python – 前端 python网路爬虫代码》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。