共计 3611 个字符,预计需要花费 10 分钟才能阅读完成。
楔子
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 语言之间的效率差别。
以上就是本次分享的所有内容,想要理解更多 python 常识欢送返回公众号:Python 编程学习圈 ,发送“J”即可收费获取,每日干货分享