<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Cython 是什么?為什么會有 Cython?

          共 4260字,需瀏覽 9分鐘

           ·

          2022-06-13 18:52




          楔子


          Cython 估計(jì)很多人都聽說過,它是用來對 Python 進(jìn)行加速的。如果你在使用 Python 編程時(shí),有過如下想法,那么 Cython 非常適合你。
          • 1)因?yàn)槟承┬枨髮?dǎo)致不得不編寫一些多重嵌套的循環(huán),而這些循環(huán)如果用 C 語言來實(shí)現(xiàn)會快上百倍,但是不熟悉 C 或者不知道 Python 如何與 C 進(jìn)行交互;
          • 2)因?yàn)?Python 解釋器的性能原因,如果將 CPython 解釋器換成 PyPy,或者干脆換一門語言,比如 Rust,將會得到明顯的性能提升,可是換不得。因?yàn)槟愕捻?xiàng)目組規(guī)定只能使用 Python 語言,解釋器只能是 CPython;
          • 3)Python 是一門動態(tài)語言,但你希望至少在數(shù)字計(jì)算方面,能夠加入可選的靜態(tài)類型,這樣可以極大地加速運(yùn)算效果。因?yàn)閱渭兊臄?shù)字相加不太需要所謂的動態(tài)性,尤其是當(dāng)你的程序中出現(xiàn)了大量的計(jì)算邏輯時(shí);
          • 4)對于一些計(jì)算密集型的部分,你希望能夠?qū)懗鲆恍╂敲?Numpy, Scipy, Pandas 的算法;
          • 5)你有一些已經(jīng)用 C、C++ 實(shí)現(xiàn)的庫,你想直接在 Python 內(nèi)部更好地調(diào)用它們,并且不使用 ctypes、cffi 等模塊;
          • 6)也許你聽說過 Python 和 C 可以無縫結(jié)合,通過 C 來為 Python 編寫擴(kuò)展模塊,將 Python 代碼中性能關(guān)鍵的部分使用 C 進(jìn)行重寫,來達(dá)到提升性能的效果。但是這需要你對 Python 解釋器有很深的了解,熟悉底層的 Python/C API,而這是一件非常痛苦的事情;
          如果你有過上面的一些想法,那么證明你的 Python 水平是很優(yōu)秀的,然而這些問題總歸是要解決的,于是 Cython 便閃亮登場了。注意:Cython 并不是一個(gè)什么實(shí)驗(yàn)性的項(xiàng)目,它出現(xiàn)的時(shí)間已經(jīng)不短了,并且在生產(chǎn)環(huán)境中久經(jīng)考驗(yàn),我們完全是有理由學(xué)習(xí)它的。
          下面讓我們開始 Cython 的學(xué)習(xí)之旅吧,悄悄說一句,我個(gè)人非常喜歡 Cython 的語法。

          Cython 是什么?


          關(guān)于 Cython,我們必須要清楚兩件事:
          1)Cython 是一門編程語言,它將 C 和 C++ 的靜態(tài)類型系統(tǒng)融合在了 Python 身上。Cython 源文件的后綴是 .pyx,它是 Python 的一個(gè)超集,語法是 Python 語法和 C 語法的混血。當(dāng)然我們說它是 Python 的一個(gè)超集,因此你寫純 Python 代碼也是可以的。
          2)當(dāng)我們編寫完 Cython 代碼時(shí),需要先將 Cython 代碼翻譯成高效的 C 代碼,然后再將 C 代碼編譯成 Python 的擴(kuò)展模塊。
          在早期,編寫 Python 擴(kuò)展都是拿 C 去寫,但是這對開發(fā)者有兩個(gè)硬性要求:一個(gè)是熟悉 C,另一個(gè)是要熟悉解釋器提供的 C API,這對開發(fā)者是一個(gè)非常大的挑戰(zhàn)。此外,拿 C 編寫代碼,開發(fā)效率也非常低。
          而 Cython 的出現(xiàn)則解決了這一點(diǎn),Cython 和 Python 的語法非常相似,我們只需要編寫 Cython 代碼,然后再由 Cython 編譯器將 Cython 代碼翻譯成 C 代碼即可。所以從這個(gè)角度上說,拿 C 寫擴(kuò)展和拿 Cython 寫擴(kuò)展是等價(jià)的。
          至于如何將 Cython 代碼翻譯成 C 代碼,則依賴于相應(yīng)的編譯器,這個(gè)編譯器本質(zhì)上就是 Python 的一個(gè)第三方模塊。它就相當(dāng)于是一個(gè)翻譯官,既然用 C 寫擴(kuò)展是一件痛苦的事情,那就拿 Cython 去寫,寫完了再幫你翻譯成 C。
          因此 Cython 的強(qiáng)大之處就在于它將 Python 和 C 結(jié)合了起來,可以讓你像寫 Python 代碼一樣的同時(shí)還可以獲得 C 的高效率。所以我們看到 Cython 相當(dāng)于是高級語言 Python 和低級語言 C 之間的一個(gè)融合,因此有人也稱 Cython 是 "克里奧爾編程語言"(creole programming language)。
          克里奧爾人是居住在西印度群島的歐洲人和非洲人的混血兒,以此來形容 Cython 也類似于是一個(gè)(Python 和 C 的)混血兒。


          為什么要有 Cython?


          Python 和 C 語言大相徑庭,為什么要將它們?nèi)诤显谝黄鹉??答案是:因?yàn)檫@兩者并不是對立的,而是互補(bǔ)的。
          Python 是高階語言、動態(tài)、易于學(xué)習(xí),并且靈活。但這些優(yōu)秀的特性是需要付出代價(jià)的,因?yàn)?Python 的動態(tài)性、以及它是解釋型語言,導(dǎo)致其運(yùn)行效率比靜態(tài)編譯型語言慢了好幾個(gè)數(shù)量級。
          而 C 語言是最古老的靜態(tài)編譯型語言之一,并且至今也被廣泛使用。從時(shí)間來算的話,其編譯器已有將近半個(gè)世紀(jì)的歷史,在性能上做了足夠的優(yōu)化,因此 C 語言是非常低級、同時(shí)又非常強(qiáng)大的。然而不同于 Python 的是,C 語言沒有提供保護(hù)措施(沒有 GC、容易內(nèi)存泄露),以及使用起來很不方便。
          所以兩個(gè)語言都是主流語言,只是特性不同使得它們被應(yīng)用在了不同的領(lǐng)域。而 Cython 的美麗之處就在于:它將 Python 語言豐富的表達(dá)能力、動態(tài)機(jī)制和 C 語言的高性能匯聚在了一起,并且代碼寫起來仍然像寫 Python 一樣。
          注意:除了極少數(shù)的例外,Python 代碼(2.x和3.x版本)已經(jīng)是有效的 Cython 代碼,因?yàn)?Cython 可以看成是 Python 的超集。并且 Cython 在 Python 語言的基礎(chǔ)上添加了一些少量的關(guān)鍵字來更好地開發(fā) C 的類型系統(tǒng),從而允許 Cython 編譯器生成高效的 C 代碼。如果你已經(jīng)知道 Python 并且對 C 或 C++ 有一定的基礎(chǔ)了解,那么你可以直接學(xué)習(xí) Cython,無需再學(xué)習(xí)其它的接口語言。
          另外,我們其實(shí)可以將 Cython 當(dāng)成兩個(gè)身份來看待:
          1)如果將 Cython 翻譯成 C,那么可以看成 Cython 的 '陰';
          2)如果將 Python 作為膠水連接 C 或者 C++,那么可以看成是 Cython 的 '陽'。
          我們可以從需要高性能的 Python 代碼開始,也可以從需要一個(gè)優(yōu)化 Python 接口的 C、C++ 開始,而我們這里是為了學(xué)習(xí) Cython,因此顯然是選擇前者。為了加速 Python 代碼,Cython 將使用可選的靜態(tài)類型聲明并通過算法來實(shí)現(xiàn)大量的性能提升,尤其是靜態(tài)類型系統(tǒng),這是實(shí)現(xiàn)高性能的關(guān)鍵。


          Cython 和 CPython 的區(qū)別?


          關(guān)于 Cython,最讓人困惑的就是它和 CPython 之間的關(guān)系,但是需要強(qiáng)調(diào)的是這兩者是完全不同的。
          首先 Python 是一門語言,它有自己的語法規(guī)則,我們按照 Python 語言規(guī)定的語法規(guī)則編寫的代碼就是 Python 源代碼。但是源代碼只是一個(gè)或多個(gè)普通的文本文件,我們需要使用 Python 語言對應(yīng)的解釋器來執(zhí)行它。
          而 Python 解釋器也會按照同樣的語法規(guī)則來對我們編寫的 Python 源代碼進(jìn)行分詞、語法解析等等,如果我們編寫的代碼不符合 Python 的語法規(guī)則,那么會報(bào)出語法錯(cuò)誤,也就是 SyntaxError。如果符合語法規(guī)范的話,那么會順利地生成抽象語法樹(Abstract Syntax Tree,簡稱 AST),然后將 AST 編譯成指令集合,也就是所謂的字節(jié)碼(bytes code),最后再執(zhí)行字節(jié)碼。
          所以 Python 源代碼是需要 Python 解釋器來操作的,如果我們想做一些事情的話,光寫成源代碼是不行的,必須要由 Python 解釋器將我們的代碼解釋成機(jī)器可以識別的指令進(jìn)行執(zhí)行才可以。而 CPython 正是 Python 語言對應(yīng)的解釋器,并且它也是官方實(shí)現(xiàn)的標(biāo)準(zhǔn)解釋器,同時(shí)還是使用最廣泛的一種解釋器?;旧衔覀兪褂玫慕忉屍鞫际?CPython,也就是從官網(wǎng)下載、然后安裝之后所得到的。
          標(biāo)準(zhǔn)解釋器 CPython 是由 C 語言實(shí)現(xiàn)的,除了 CPython 之外還有 Jython(java實(shí)現(xiàn)的 Python 解釋器)、PyPy(Python 語言實(shí)現(xiàn)的 Python 解釋器)等等??傊O(shè)計(jì)出一門語言,還要有相應(yīng)的解釋器才可以;至于編譯型語言,則是對應(yīng)的編譯器。
          最后重點(diǎn)來了,我們說 CPython 解釋器是由 C 實(shí)現(xiàn)的,它給 Python 語言提供了 C 級別的接口,也就是熟知的 Python/C API。比如:Python 的列表,底層對應(yīng)的是 PyListObject;字典則對應(yīng) PyDictObject,等等等等。
          所以當(dāng)我們在 Python 中創(chuàng)建一個(gè)列表,那么 CPython 在執(zhí)行的時(shí)候,就會在底層創(chuàng)建一個(gè) PyListObject。因?yàn)?CPython 是用 C 來實(shí)現(xiàn)的,最終肯定是將 Python 代碼翻譯成 C 級別的代碼,然后再變成機(jī)器碼交給 CPU 執(zhí)行。
          而 Cython 也是如此,Cython 代碼也要被翻譯成 C 代碼,然后 C 代碼再變成擴(kuò)展(本質(zhì)上也是機(jī)器碼),導(dǎo)入之后直接執(zhí)行,而無需動態(tài)解釋。因此 Cython 是一門語言,它并不是Python 解釋器的另一種實(shí)現(xiàn),它的地位和 CPython 不是等價(jià)的,不過和 Python 是平級的。
          總結(jié):Cython 是一門語言,可以通過 Cython 源代碼生成高效的 C 代碼,再將 C 代碼編譯成擴(kuò)展模塊,同樣需要 CPython 來進(jìn)行調(diào)用。
          以上我們就解釋了什么是 Cython,以及為什么需要 Cython。下一篇文章我們來比較一下,Cython, Python, C 擴(kuò)展, 還有原生的 C 語言之間的效率差異。
          所以這又是一個(gè)新系列,通過一點(diǎn)點(diǎn)地深入了解,你會發(fā)現(xiàn) Cython 的魅力。
          下一篇:《比較一下 Python、C、C 擴(kuò)展、Cython 之間的差異
          Python貓技術(shù)交流群開放啦!群里既有國內(nèi)一二線大廠在職員工,也有國內(nèi)外高校在讀學(xué)生,既有十多年碼齡的編程老鳥,也有中小學(xué)剛剛?cè)腴T的新人,學(xué)習(xí)氛圍良好!想入群的同學(xué),請?jiān)诠杻?nèi)回復(fù)『交流群』,獲取貓哥的微信(謝絕廣告黨,非誠勿擾?。?/span>~


          還不過癮?試試它們




          Python 程序調(diào)試分析大殺器合集

          為什么繼承 Python 內(nèi)置類型會出問題?!

          2021年,你應(yīng)該知道的Python打包指南

          為什么 Python 不用聲明類型?

          基于 Python 探針完成調(diào)用庫的數(shù)據(jù)提取

          終于,Python 標(biāo)準(zhǔn)庫要做“瘦身手術(shù)”了!


          如果你覺得本文有幫助
          請慷慨分享點(diǎn)贊,感謝啦!
          瀏覽 77
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  波多野42部无码喷潮更新时间 | 围产精品久久久久久久黄无码 | 国产免费一区二区在线A片视频 | 麻豆久久艹 | 欧熟视频|