首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用 Cython 造个轮子

作者丨Nugine

https://zhuanlan.zhihu.com/c_168195059

在本篇文章中,我要向你展示使用 Cython 扩展 Python 的技巧。

如果你同时有 C/C++和 Python 的编码能力,我相信你会喜欢这个的。

我们要造的轮子是一个最简单的栈的实现,用 C/C++来编写能够减小不必要的开销,带来显著的加速。

步骤

建立目录

编写 C++文件

编写 pyx 文件

直接编译

测试

1. 建立目录

首先,建立我们的工作目录。

32 位版本和 64 位版本会带来不同的问题。我的 C 库是 32 位的,所以 python 库必须也是 32 位。

使用 pipenv 指定 python 版本,并安装 Cython。

2. 编写 C++文件

按 Python 官方文档,这里 C++必须用 C 的方式编译,所以需要加上 extern "C"。

"c_stack.h"

"c_stack.cpp"

最简单的栈实现,只有 push,peek,pop 三个接口,作为示例足够了。

3. 编写 pyx 文件

Cython 使用 C 与 Python 混合的语法简化了扩展 Python 的步骤。

编写起来十分简单,前提是事先了解它的语法。

"pystack.pyx"

分为四个部分:

注释指定相应的 cpp 文件。

从 CPython 导入 C 符号:PyObject,Py_INCREF,Py_DECREF。

从"c_stack.h"导入 C 符号: C_Stack,以及它的接口。

将其包装为 Python 对象。

注意点:

在 C 实现中,当栈为空时,返回了空指针。Python 实现中检查空指针,并抛出异常 StackEmpty.

PyObject* 和 object 并不等同,需要做类型转换。

push 和 pop 时要正确操作引用计数,否则会让 Python 解释器直接崩溃。一开始不知道这个,懵逼好久,偶然间看到报错与 gc 有关,才想到引用计数的问题。

4. 直接编译

生成三个文件: pystack.cpp,pystack.html,pystack.cp36-win32.pyd

pyx 编译到 cpp,再由 C 编译器编译为 pyd。

html 是 cython 提示,指出 pyx 代码中与 python 的交互程度。

pyd 就是最终的 Python 库了。

5. 测试一下

"test.py"

与正常 Python 对象表现相同,完美!

6. 应用

本篇文章展示了最简单的 Cython 造轮子技巧,希望能为即将进坑和已经进坑的同学提供一块垫脚石。如果对你有所帮助,请点赞和收藏。

推荐↓↓↓

觉得我们“好看”的点亮它~

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181225B19P0U00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券