Cython 估計很多人都聽說過,它是用來對 Python 進行加速的。如果你在使用 Python 編程時,有過如下想法,那么 Cython 非常適合你。
- 因為某些需求導致不得不編寫一些多重嵌套的循環(huán),而這些循環(huán)如果用 C 語言來實現(xiàn)會快上百倍,但是不熟悉 C 或者不知道 Python 如何與 C 進行交互;
- 因為 Python 解釋器的性能原因,如果將 CPython 解釋器換成 PyPy,或者干脆換一門語言,比如 Rust,將會得到明顯的性能提升,可是換不得。因為你的項目組規(guī)定只能使用 Python 語言,解釋器只能是 CPython;
- Python 是一門動態(tài)語言,但你希望至少在數(shù)字計算方面,能夠加入可選的靜態(tài)類型,這樣可以極大地加速運算效果。因為單純的數(shù)字相加不太需要所謂的動態(tài)性,尤其是當你的程序中出現(xiàn)了大量的計算邏輯時;
- 對于一些計算密集型的部分,你希望能夠寫出一些媲美 Numpy, Scipy, Pandas 的算法;
- 你有一些已經用 C、C++ 實現(xiàn)的庫,你想直接在 Python 內部更好地調用它們,并且不使用 ctypes、cffi 等模塊;
- 也許你聽說過 Python 和 C 可以無縫結合,通過 C 來為 Python 編寫擴展模塊,將 Python 代碼中性能關鍵的部分使用 C 進行重寫,來達到提升性能的效果。但是這需要你對 Python 解釋器有很深的了解,熟悉底層的 Python/C API,而這是一件非常痛苦的事情;
如果你有過上面的一些想法,那么證明你的 Python 水平是很優(yōu)秀的,然而這些問題總歸是要解決的,于是 Cython 便閃亮登場了。注意:Cython 并不是一個什么實驗性的項目,它出現(xiàn)的時間已經不短了,并且在生產環(huán)境中久經考驗,我們完全是有理由學習它的。
Cython 是什么?
關于 Cython,我們必須要清楚兩件事:
- Cython 是一門編程語言,它將 C 和 C++ 的靜態(tài)類型系統(tǒng)融合在了 Python 身上。Cython 源文件的后綴是 .pyx,它是 Python 的一個超集,語法是 Python 語法和 C 語法的混血。當然我們說它是 Python 的一個超集,因此你寫純 Python 代碼也是可以的。
- 當我們編寫完 Cython 代碼時,需要先將 Cython 代碼翻譯成高效的 C 代碼,然后再將 C 代碼編譯成 Python 的擴展模塊。
在早期,編寫 Python 擴展都是拿 C 去寫,但是這對開發(fā)者有兩個硬性要求:一個是熟悉 C,另一個是要熟悉解釋器提供的 C API,這對開發(fā)者是一個非常大的挑戰(zhàn)。此外,拿 C 編寫代碼,開發(fā)效率也非常低。而 Cython 的出現(xiàn)則解決了這一點,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 語言大相徑庭,為什么要將它們融合在一起呢?答案是:因為這兩者并不是對立的,而是互補的。
Python 是高階語言、動態(tài)、易于學習,并且靈活。但這些優(yōu)秀的特性是需要付出代價的,因為 Python 的動態(tài)性、以及它是解釋型語言,導致其運行效率比靜態(tài)編譯型語言慢了好幾個數(shù)量級。
而 C 語言是最古老的靜態(tài)編譯型語言之一,并且至今也被廣泛使用。從時間來算的話,其編譯器已有將近半個世紀的歷史,在性能上做了足夠的優(yōu)化,因此 C 語言是非常低級、同時又非常強大的。然而不同于 Python 的是,C 語言沒有提供保護措施(沒有 GC、容易內存泄露),以及使用起來很不方便。
所以兩個語言都是主流語言,只是特性不同使得它們被應用在了不同的領域。而 Cython 的美麗之處就在于:它將 Python 語言豐富的表達能力、動態(tài)機制和 C 語言的高性能匯聚在了一起,并且代碼寫起來仍然像寫 Python 一樣。
注意:除了極少數(shù)的例外,Python 代碼(2.x和3.x版本)已經是有效的 Cython 代碼,因為 Cython 可以看成是 Python 的超集。并且 Cython 在 Python 語言的基礎上添加了一些少量的關鍵字來更好地開發(fā) C 的類型系統(tǒng),從而允許 Cython 編譯器生成高效的 C 代碼。如果你已經知道 Python 并且對 C 或 C++ 有一定的基礎了解,那么你可以直接學習 Cython,無需再學習其它的接口語言。
另外,我們其實可以將 Cython 當成兩個身份來看待:
- 如果將 Cython 翻譯成 C,那么可以看成 Cython 的 '陰';
- 如果將 Python 作為膠水連接 C 或者 C++,那么可以看成是 Cython 的 '陽'。
我們可以從需要高性能的 Python 代碼開始,也可以從需要一個優(yōu)化 Python 接口的 C、C++ 開始,而我們這里是為了學習 Cython,因此顯然是選擇前者。為了加速 Python 代碼,Cython 將使用可選的靜態(tài)類型聲明并通過算法來實現(xiàn)大量的性能提升,尤其是靜態(tài)類型系統(tǒng),這是實現(xiàn)高性能的關鍵。
Cython 和 CPython 的區(qū)別?
關于 Cython,最讓人困惑的就是它和 CPython 之間的關系,但是需要強調的是這兩者是完全不同的。
首先 Python 是一門語言,它有自己的語法規(guī)則,我們按照 Python 語言規(guī)定的語法規(guī)則編寫的代碼就是 Python 源代碼。但是源代碼只是一個或多個普通的文本文件,我們需要使用 Python 語言對應的解釋器來執(zhí)行它。
而 Python 解釋器也會按照同樣的語法規(guī)則來對我們編寫的 Python 源代碼進行分詞、語法解析等等,如果我們編寫的代碼不符合 Python 的語法規(guī)則,那么會報出語法錯誤,也就是 SyntaxError。如果符合語法規(guī)范的話,那么會順利地生成抽象語法樹(Abstract Syntax Tree,簡稱 AST),然后將 AST 編譯成指令集合,也就是所謂的字節(jié)碼(bytes code),最后再執(zhí)行字節(jié)碼。
所以 Python 源代碼是需要 Python 解釋器來操作的,如果我們想做一些事情的話,光寫成源代碼是不行的,必須要由 Python 解釋器將我們的代碼解釋成機器可以識別的指令進行執(zhí)行才可以。而 CPython 正是 Python 語言對應的解釋器,并且它也是官方實現(xiàn)的標準解釋器,同時還是使用最廣泛的一種解釋器?;旧衔覀兪褂玫慕忉屍鞫际?CPython,也就是從官網下載、然后安裝之后所得到的。
標準解釋器 CPython 是由 C 語言實現(xiàn)的,除了 CPython 之外還有 Jython(java實現(xiàn)的 Python 解釋器)、PyPy(Python 語言實現(xiàn)的 Python 解釋器)等等??傊O計出一門語言,還要有相應的解釋器才可以;至于編譯型語言,則是對應的編譯器。
最后重點來了,我們說 CPython 解釋器是由 C 實現(xiàn)的,它給 Python 語言提供了 C 級別的接口,也就是熟知的 Python/C API。比如:Python 的列表,底層對應的是 PyListObject;字典則對應 PyDictObject,等等等等。
所以當我們在 Python 中創(chuàng)建一個列表,那么 CPython 在執(zhí)行的時候,就會在底層創(chuàng)建一個 PyListObject。因為 CPython 是用 C 來實現(xiàn)的,最終肯定是將 Python 代碼翻譯成 C 級別的代碼,然后再變成機器碼交給 CPU 執(zhí)行。
而 Cython 也是如此,Cython 代碼也要被翻譯成 C 代碼,然后 C 代碼再變成擴展(本質上也是機器碼),導入之后直接執(zhí)行,而無需動態(tài)解釋。因此 Cython 是一門語言,它并不是Python 解釋器的另一種實現(xiàn),它的地位和 CPython 不是等價的,不過和 Python 是平級的。
總結:Cython 是一門語言,可以通過 Cython 源代碼生成高效的 C 代碼,再將 C 代碼編譯成擴展模塊,同樣需要 CPython 來進行調用。
審核編輯:符乾江
-
源代碼
+關注
關注
96文章
2945瀏覽量
66748 -
python
+關注
關注
56文章
4797瀏覽量
84691
發(fā)布評論請先 登錄
相關推薦
評論