楔子

Cython 估计很多人都听说过,它是用来对 Python 进行加速的。如果你在使用 Python 编程时,有过如下想法,那么 Cython 非常适合你。

  • 1)因为某些需求导致不得不编写一些多重嵌套的循环,而这些循环如果用 C 语言来实现会快上百倍,但是不熟悉 C 或者不知道 Python 如何与 C 进行交互;

  • 2)因为 Python 解释器的性能原因,如果将 CPython 解释器换成 PyPy,或者干脆换一门语言,比如 Rust,将会得到明显的性能提升,可是换不得。因为你的项目组规定只能使用 Python 语言,解释器只能是 CPython;

  • 3)Python 是一门动态语言,但你希望至少在数字计算方面,能够加入可选的静态类型,这样可以极大地加速运算效果。因为单纯的数字相加不太需要所谓的动态性,尤其是当你的程序中出现了大量的计算逻辑时;

  • 4)对于一些计算密集型的部分,你希望能够写出一些媲美 Numpy, Scipy, Pandas 的算法;

  • 5)你有一些已经用 C、C++ 实现的库,你想直接在 Python 内部更好地调用它们,并且不使用 ctypes、cffi 等模块;

  • 6)也许你听说过 Python 和 C 可以无缝结合,通过 C 来为 Python 编写扩展模块,将 Python 代码中性能关键的部分使用 C 进行重写,来达到提升性能的效果。但是这需要你对 Python 解释器有很深的了解,熟悉底层的 Python/C API,而这是一件非常痛苦的事情;

如果你有过上面的一些想法,那么证明你的 Python 水平是很优秀的,然而这些问题总归是要解决的,于是 Cython 便闪亮登场了。注意:Cython 并不是一个什么实验性的项目,它出现的时间已经不短了,并且在生产环境中久经考验,我们完全是有理由学习它的。

下面让我们开始 Cython 的学习之旅吧,悄悄说一句,我个人非常喜欢 Cython 的语法。

Cython 是什么?

关于 Cython,我们必须要清楚两件事:

1)Cython 是一门编程语言,它将 C 和 C++ 的静态类型系统融合在了 Python 身上。Cython 源文件的后缀是 .pyx,它是 Python 的一个超集,语法是 Python 语法和 C 语法的混血。当然我们说它是 Python 的一个超集,因此你写纯 Python 代码也是可以的。

2)当我们编写完 Cython 代码时,需要先将 Cython 代码翻译成高效的 C 代码,然后再将 C 代码编译成 Python 的扩展模块。

在早期,编写 Python 扩展都是拿 C 去写,但是这对开发者有两个硬性要求:一个是熟悉 C,另一个是要熟悉解释器提供的 C API,这对开发者是一个非常大的挑战。此外,拿 C 编写代码,开发效率也非常低。

而 Cython 的出现则解决了这一点,Cython 和 Python 的语法非常相似,我们只需要编写 Cython 代码,然后再由 Cython 编译器将 Cython 代码翻译成 C 代码即可。所以从这个角度上说,拿 C 写扩展和拿 Cython 写扩展是等价的。

至于如何将 Cython 代码翻译成 C 代码,则依赖于相应的编译器,这个编译器本质上就是 Python 的一个第三方模块。它就相当于是一个翻译官,既然用 C 写扩展是一件痛苦的事情,那就拿 Cython 去写,写完了再帮你翻译成 C。

因此 Cython 的强大之处就在于它将 Python 和 C 结合了起来,可以让你像写 Python 代码一样的同时还可以获得 C 的高效率。所以我们看到 Cython 相当于是高级语言 Python 和低级语言 C 之间的一个融合,因此有人也称 Cython 是 "克里奥尔编程语言"(creole programming language)。

克里奥尔人是居住在西印度群岛的欧洲人和非洲人的混血儿,以此来形容 Cython 也类似于是一个(Python 和 C 的)混血儿。

为什么要有 Cython?

Python 和 C 语言大相径庭,为什么要将它们融合在一起呢?答案是:因为这两者并不是对立的,而是互补的。

Python 是高阶语言、动态、易于学习,并且灵活。但这些优秀的特性是需要付出代价的,因为 Python 的动态性、以及它是解释型语言,导致其运行效率比静态编译型语言慢了好几个数量级。

而 C 语言是最古老的静态编译型语言之一,并且至今也被广泛使用。从时间来算的话,其编译器已有将近半个世纪的历史,在性能上做了足够的优化,因此 C 语言是非常低级、同时又非常强大的。然而不同于 Python 的是,C 语言没有提供保护措施(没有 GC、容易内存泄露),以及使用起来很不方便。

所以两个语言都是主流语言,只是特性不同使得它们被应用在了不同的领域。而 Cython 的美丽之处就在于:它将 Python 语言丰富的表达能力、动态机制和 C 语言的高性能汇聚在了一起,并且代码写起来仍然像写 Python 一样。

注意:除了极少数的例外,Python 代码(2.x和3.x版本)已经是有效的 Cython 代码,因为 Cython 可以看成是 Python 的超集。并且 Cython 在 Python 语言的基础上添加了一些少量的关键字来更好地开发 C 的类型系统,从而允许 Cython 编译器生成高效的 C 代码。如果你已经知道 Python 并且对 C 或 C++ 有一定的基础了解,那么你可以直接学习 Cython,无需再学习其它的接口语言。

另外,我们其实可以将 Cython 当成两个身份来看待:

1)如果将 Cython 翻译成 C,那么可以看成 Cython 的 '阴';

2)如果将 Python 作为胶水连接 C 或者 C++,那么可以看成是 Cython 的 '阳'。

我们可以从需要高性能的 Python 代码开始,也可以从需要一个优化 Python 接口的 C、C++ 开始,而我们这里是为了学习 Cython,因此显然是选择前者。为了加速 Python 代码,Cython 将使用可选的静态类型声明并通过算法来实现大量的性能提升,尤其是静态类型系统,这是实现高性能的关键。

Cython 和 CPython 的区别?

关于 Cython,最让人困惑的就是它和 CPython 之间的关系,但是需要强调的是这两者是完全不同的。

首先 Python 是一门语言,它有自己的语法规则,我们按照 Python 语言规定的语法规则编写的代码就是 Python 源代码。但是源代码只是一个或多个普通的文本文件,我们需要使用 Python 语言对应的解释器来执行它。

而 Python 解释器也会按照同样的语法规则来对我们编写的 Python 源代码进行分词、语法解析等等,如果我们编写的代码不符合 Python 的语法规则,那么会报出语法错误,也就是 SyntaxError。如果符合语法规范的话,那么会顺利地生成抽象语法树(Abstract Syntax Tree,简称 AST),然后将 AST 编译成指令集合,也就是所谓的字节码(bytes code),最后再执行字节码。

所以 Python 源代码是需要 Python 解释器来操作的,如果我们想做一些事情的话,光写成源代码是不行的,必须要由 Python 解释器将我们的代码解释成机器可以识别的指令进行执行才可以。而 CPython 正是 Python 语言对应的解释器,并且它也是官方实现的标准解释器,同时还是使用最广泛的一种解释器。基本上我们使用的解释器都是 CPython,也就是从官网下载、然后安装之后所得到的。

标准解释器 CPython 是由 C 语言实现的,除了 CPython 之外还有 Jython(java实现的 Python 解释器)、PyPy(Python 语言实现的 Python 解释器)等等。总之设计出一门语言,还要有相应的解释器才可以;至于编译型语言,则是对应的编译器。

最后重点来了,我们说 CPython 解释器是由 C 实现的,它给 Python 语言提供了 C 级别的接口,也就是熟知的 Python/C API。比如:Python 的列表,底层对应的是 PyListObject;字典则对应 PyDictObject,等等等等。

所以当我们在 Python 中创建一个列表,那么 CPython 在执行的时候,就会在底层创建一个 PyListObject。因为 CPython 是用 C 来实现的,最终肯定是将 Python 代码翻译成 C 级别的代码,然后再变成机器码交给 CPU 执行。

而 Cython 也是如此,Cython 代码也要被翻译成 C 代码,然后 C 代码再变成扩展(本质上也是机器码),导入之后直接执行,而无需动态解释。因此 Cython 是一门语言,它并不是Python 解释器的另一种实现,它的地位和 CPython 不是等价的,不过和 Python 是平级的。

总结:Cython 是一门语言,可以通过 Cython 源代码生成高效的 C 代码,再将 C 代码编译成扩展模块,同样需要 CPython 来进行调用。

以上我们就解释了什么是 Cython,以及为什么需要 Cython。下一篇文章我们来比较一下,Cython, Python, C 扩展, 还有原生的 C 语言之间的效率差异。

所以这又是一个新系列,通过一点点地深入了解,你会发现 Cython 的魅力。

下一篇:《比较一下 Python、C、C 扩展、Cython 之间的差异》

Python猫技术交流群开放啦!群里既有国内一二线大厂在职员工,也有国内外高校在读学生,既有十多年码龄的编程老鸟,也有中小学刚刚入门的新人,学习氛围良好!想入群的同学,请在公号内回复『交流群』,获取猫哥的微信(谢绝广告党,非诚勿扰!)~

还不过瘾?试试它们

Python 程序调试分析大杀器合集

为什么继承 Python 内置类型会出问题?!

2021年,你应该知道的Python打包指南

为什么 Python 不用声明类型?

基于 Python 探针完成调用库的数据提取

终于,Python 标准库要做“瘦身手术”了!

如果你觉得本文有帮助

请慷慨分享点赞,感谢啦

Cython 是什么?为什么会有 Cython?相关推荐

  1. jsonarray转化list对象_第8篇:Cython的面向对象--Python类 vs Cython扩展类

    在Python中,一切都是对象. 具体来说是什么意思? 在最基本的层面上,一个对象具有三样东西 标识(id):对象的标识将其与其他对象区分开来,并由id内置函数提供 属性值(value):对象的值就是 ...

  2. 编译ceph源码:cython module not found问题的解决

    环境:centos7.5 ceph版本:12.2.1 在当前环境对ceph源码rpm包进行重新编译 执行命令rpmbuild --rebuild ceph-12.2.1-0.el7.src.rpm 最 ...

  3. python转cython_用Cython加速Python到“起飞”(推荐)

    事先声明,标题没有把"Python"错打成"Cython",因为要讲的就是名为"Cython"的东西. Cython是让Python脚本支持 ...

  4. Py之cython:python库之cython的简介、安装、使用方法之详细攻略

    Py之cython:python库之cython的简介.安装.使用方法之详细攻略 目录 cython的简介 cython的安装 cython的使用方法 cython的简介 Cython语言使得Pyth ...

  5. python 大项目使用cython_提升6.75倍!利用Cython为Python代码加速

    全文共2012字,预计学习时长4分钟 图片来源:Unsplash 如果你曾经用Python编写过代码,可能会发现等待某些代码块执行的时间比预期要长.尽管可以通过一些方法提高其代码效率,但它的反应速度仍 ...

  6. 扩展方法必须在非泛型静态类中定义_第11篇:Cython面向对象编程--扩展类的实例化...

    我们前篇谈到了Cython的访问控制,并且谈论了cdef class关键字的底层操作,顺带也谈论了Python类为什么会比Cython类慢的原因.本篇我们将介绍Cython扩展类的初始化 Cython ...

  7. 转载:比Python快100倍,利用spaCy和Cython实现高速NLP项目

    Cython 是一个工具包,可以使你在 Python 中编译 C 语言,这就是为什么 numpy 和 pandas 很快的原因,Cython 就是 Python 的超集.在本文中,作者将为我们介绍他的 ...

  8. Cython——[FutureWarning: Cython directive ‘language_level’ not set, using 2 for now (Py2)]解决方案

    问题描述 FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2) 问题分析 解决方案 在每个.p ...

  9. 真香!spaCy+Cython比Python快100倍.....

    选自Medium      作者:Thomas Wolf 编译:机器之心(almosthuman2014) Cython 是一个工具包,可以使你在 Python 中编译 C 语言,这就是为什么 num ...

  10. python代码加密cython_利用Cython对python代码进行加密

    利用Cython对python代码进行加密 Cython是属于PYTHON的超集,他首先会将PYTHON代码转化成C语言代码,然后通过c编译器生成可执行文件.优势:资源丰富,适合快速开发.翻译成C后速 ...

最新文章

  1. 国行版HomePod售价2799元,本周五发售
  2. python 一份简单的车辆环视全景系统实现图像拼接缝融合
  3. webapi 返回类型
  4. 分布式锁编写及调试分析
  5. maven 排除配置文件打包_Maven打包pom里面配置exclude 排除掉环境相关的配置文件...
  6. 如何解决区块链钱包更新慢问题?
  7. mysql 事务 隔离级别_MySQL的四种事务隔离级别
  8. 高通的快充协议_高通QC5.0快充发布:百瓦级时代,高通被国产厂商牵着鼻子走了?...
  9. WindowsXP 进程分析
  10. LVM逻辑卷管理@设备、格式、摩、引导自己主动安装一个完整的章节
  11. 放弃微博,继续回来写月经
  12. PS 批量导入图片制作 gif
  13. js如何实现扫描身份证识别_基于javascript实现根据身份证号码识别性别和年龄
  14. OriginPro 绘制柱状图(特别是用于对比实验时)
  15. 携程校招——携程海洋馆的海豚小宝宝(C++)
  16. HTML+CSS(part 1)
  17. 怎样设置台式计算机无线上网,设置无线网络
  18. MacBook 版 IDEA- 2022.2 新版本UI插件
  19. android 根据宽度调整字体大小,android 字体大小 根据分辨率 自动调整
  20. 学习通考试刷题(ocs网课助手)

热门文章

  1. 华东师范2018研究生复试上机题题解
  2. sequelize 的op模块
  3. 针对于“上传文件”和“触发方式” 的解决方案(Antd个例)
  4. 百分百胜率只是个例,我们追求的目标是稳步获利!
  5. 数据集市是什么?数据集市和数据仓库有什么区别
  6. 解决win10使用Fiddler4无法手机抓包的问题(真正的大招!)
  7. 欧拉公式推导(e^iπ+1=0)
  8. 【机器学习】——梯度下降法的收敛性证明(详解)
  9. 生成哑变量的几种方法
  10. 如何在服务器上编辑配置文件