为什么会有这么多python?其实python并不是编程语言!
Python是出類拔萃的
然而,這是一句非常模棱兩可的話。這里的"Python"到底指的是什么? 是Python的抽象接口嗎?是Python的通用實(shí)現(xiàn)CPython嗎(不要把CPython跟Cython搞混了)?亦或者指的完全是其他的東西呢?可能我另外指的是Jython,或者IronPython,或者是PyPy。也或者轉(zhuǎn)而談?wù)摰挠质荝Python或者RubyPython(這兩者是完全不同的東西)。
上面提到的那些技術(shù)經(jīng)常被提起和引用, 它們的使用目的和場(chǎng)景是完全不一樣的(至少,它們的操作方式是完全不一樣的)
自從我使用Python工作以來,我已經(jīng)用過了各種各樣的.*ython工具了。但是直到最近我才花時(shí)間去理解到底它們是干嘛的,它們是怎樣工作的,為什么它們是不可或缺的。
在這篇文章里面,我會(huì)介紹各種Python的實(shí)現(xiàn),最后以對(duì)PyPy的介紹結(jié)尾, 因?yàn)槲覀€(gè)人認(rèn)為它是Python的未來。
所有的都從理解什么是"Python"開始。
如果你對(duì)機(jī)器碼,虛擬機(jī)之類的很熟了,你可以跳過開頭,直接從 "即時(shí)編譯: PyPy和它的未來" 這部分開始看起。
Python是解釋型的還是編譯型的?
這是個(gè)Python新人都會(huì)迷惑的問題。
首先需要明了的是Python只是一個(gè)接口。有一個(gè)關(guān)于Python應(yīng)該做什么以及怎么做的具體說明(就像其他任何接口一樣 ),并且對(duì)應(yīng)的有很多具體的實(shí)現(xiàn)(也像其他接口一樣)。
其次需要知道的是“解釋型”和“編譯型”是具體實(shí)現(xiàn)的特性,而不是接口的特性。
所以,這個(gè)問題本身就沒有組織好。
Python是解釋型還是編譯型的?這個(gè)問題真的沒有組織好。
對(duì)使用最廣泛的實(shí)現(xiàn)(CPython:用C實(shí)現(xiàn)的,通常簡單的說成Python,若你不知道我所說的這些,那很肯能你在使用的就是CPython)而言,這個(gè)問題的答案是:解釋型,但帶有一些編譯型特征。CPython把Python源碼編譯*成字節(jié)碼,之后再解釋這些字節(jié)碼,執(zhí)行之。
*注意:這個(gè)編譯不是通常意義上的編譯。通常我們說的編譯,是指把高級(jí)語言代碼轉(zhuǎn)換成機(jī)器碼。但這里實(shí)際上是一種種類的編譯。(譯者,這句話不是很懂,原文是it is a ‘compilation’ of sorts,不知作何解,求教各位讀者。)
再詳細(xì)看下上面的答案吧,這有助于我們理解本文中后面會(huì)講到的幾個(gè)概念。
字節(jié)碼 vs. 機(jī)器碼
了解字節(jié)碼和機(jī)器碼(或者native code)的區(qū)別是很重要的,最好的辦法或許是看看例子:
- C代碼被編譯成機(jī)器碼,將在處理器上直接執(zhí)行。每一條指令控制CPU工作。
- Java代碼被編譯成字節(jié)碼,將在Java虛擬機(jī)(JVM)這個(gè)抽象的計(jì)算機(jī)上執(zhí)行。每一條指令由JVM處理,JVM同計(jì)算機(jī)本身之間交互。
簡而言之:機(jī)器碼快的多,但字節(jié)碼更易遷移,也更安全。
機(jī)器碼隨機(jī)器的變化而變化,但字節(jié)碼在所有的機(jī)器上都是一樣的。有人可能會(huì)認(rèn)為機(jī)器碼是對(duì)特定環(huán)境優(yōu)化了的。
字節(jié)碼隨后在CPython虛擬機(jī)上執(zhí)行。
初學(xué)者常常因?yàn)榭吹?pyc文件而假設(shè)Python是編譯型的。這也有一些合理性:.pyc文件正式之后要解釋的字節(jié)碼文件。所以,你若之前運(yùn)行過你的Python代碼,生成了.pyc文件,再次運(yùn)行時(shí)就要快得多,因?yàn)椴恍枰俅尉幾g生成字節(jié)碼了。
可選的虛擬機(jī):Jython,IronPython等
正如我之前所述,Python有很多實(shí)現(xiàn)。前面也提到,CPython是最通用的。這是一個(gè)用C實(shí)現(xiàn)的,被認(rèn)為是”默認(rèn)“的實(shí)現(xiàn)。
但其他的呢?其中最顯赫的之一就是Jython,一個(gè)用Java實(shí)現(xiàn)的采用了JVM的實(shí)現(xiàn)。CPython生成在CPython虛擬機(jī)上運(yùn)行的字節(jié)碼,而Jython生成在JVM上運(yùn)行的java字節(jié)碼(這同編譯Java程序生成java字節(jié)碼的過程是一樣的)。
”為啥你要用其他的實(shí)現(xiàn)?”,你可能會(huì)如此發(fā)問。好吧,對(duì)開發(fā)者而言,不同的實(shí)現(xiàn)對(duì)不同的技術(shù)難題的支持程度不一樣。
CPython中很容易為你的Python代碼寫C擴(kuò)展,因?yàn)樽罱K都是由C解釋器執(zhí)行的。另一方面,Jython則使得和其他java程序共同工作很容易:無需其他工作,你就可導(dǎo)入任何Java類,在你的Jython程序中使用其他Java類。(題外話,若你沒有認(rèn)真思考,這一段會(huì)很難。此時(shí)我們已經(jīng)在討論把不同語言的代碼混在一起,并編譯成同一程序。(Rostin?提出混合Fortran和C代碼編程已經(jīng)有一段時(shí)間了。所以,這并不新鮮,但仍然很酷。))
下面是一個(gè)例子,一段合法的Jython代碼:
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51 >>> from java.util import HashSet >>> s = HashSet(5) >>> s.add("Foo") >>> s.add("Bar") >>> s [Foo, Bar]IronPython是另一很流行的Python 實(shí)現(xiàn),完全用C#實(shí)現(xiàn),針對(duì).NET平臺(tái)。她運(yùn)行在可以叫做.NET虛擬機(jī)的平臺(tái)上,這是微軟的?Common Language Runtime (CLR),同JVM相對(duì)應(yīng)。
你可能會(huì)說,Jython:Java::IronPython:C#。它們各自運(yùn)行在相同的虛擬機(jī)上,你能從你的IronPython中導(dǎo)入C#的類,從你寫的Jython代碼中帶入Java類,等等
你完全可以不用任何非CPython的實(shí)現(xiàn)就能完成你手上的任何工作。但是使用這些技術(shù)也是有很多的好處的,大部分取決于你現(xiàn)在所使用的技術(shù)棧。 你使用了很多基于JVM的語言?Jython就是為你準(zhǔn)備的。使用的都是.NET世界的語言?那么你應(yīng)該試試IronPython了(或許你已經(jīng)在用了)
順便說一下(盡管這不是使用不同的實(shí)現(xiàn)的理由),注意Python的各種實(shí)現(xiàn)在對(duì)待你的Python源碼的時(shí)候所做的處理方式是完全不一樣的。然后這些差異是很小的,由于這些實(shí)現(xiàn)都在不停的發(fā)展改進(jìn)中,隨著時(shí)間的推移,這些差異會(huì)慢慢融合和兼容。比如,IronPython默認(rèn)情況下使用Unicode字符串,但是在2.x版本的CPython中默認(rèn)是ASCII字符串(如果使用了非ASCII字符串,會(huì)拋出一個(gè)UnicodeEncodeError錯(cuò)誤),但是在3.x版本里面CPythong已經(jīng)默認(rèn)支持Unicode字符串了。
即時(shí)編譯: PyPy和它的未來
我們已經(jīng)有了一個(gè)使用C寫的Python實(shí)現(xiàn),一個(gè)用Java寫的,一個(gè)用C#寫的。接下來就是:用Python寫的Python實(shí)現(xiàn)(有心人可能會(huì)注意這句話有點(diǎn)問題,是個(gè)死循環(huán),^_^)
接下來我們看下什么地方容易搞混淆。首先,我們討論下即時(shí)編譯器JIT
JIT: 為什么會(huì)有這個(gè)?它的原理是什么?
大家都知道本地機(jī)器碼的速度比字節(jié)碼的速度快很多。那么,如果我們能將一些字節(jié)碼直接編譯成本地機(jī)器碼再去運(yùn)行它會(huì)怎樣呢?我們必須花費(fèi)一些代價(jià)(比如時(shí)間)在編譯字節(jié)碼到本地機(jī)器碼上,如果最終的運(yùn)行時(shí)間更快,那么這個(gè)代價(jià)就是值得的。這就是JIT編譯器的動(dòng)機(jī),一種混合了解釋器和編譯器好處的技術(shù)。簡單來講,JIT就是想通過編譯技術(shù)提升腳本解釋器系統(tǒng)的速度。
例如, 被JIT(及時(shí)編譯)采用的通用方法:
這是關(guān)于PyPy的用處: 把JIT代入Python語言 (參看前面成果的附錄).當(dāng)然也有其他目的: PyPy 目標(biāo)是成為一個(gè)跨平臺(tái),輕內(nèi)存,支持stackless(譯注:stackless為python提供微線程擴(kuò)展,具有并發(fā)特性)。 但是及時(shí)編譯才是它真正的賣點(diǎn)。 基于一系列時(shí)間測(cè)試的平均, 據(jù)說性能上能提高6.27倍. 停一下, 看看下面這個(gè)由PyPy Speed Center提供的圖表:
PyPy is Hard to Understand
PyPy具有巨大的潛力,在這一點(diǎn)上,它與CPython高度兼容所以它能運(yùn)行Flask,Django等等)。
但關(guān)于PyPy有許多困惑 (例如,荒謬的建議創(chuàng)造一種PyPyPy…語言). 按我的觀點(diǎn),那主要是因?yàn)镻yPy實(shí)際上是兩種東西:
一種用RPython?(非Python (我之前撒謊了))編寫的Python解釋器。 RPython是Python的子集,具有靜態(tài)類型。在Python里,最難嚴(yán)格推論類型?(為什么這么困難,考慮下下面的事實(shí):
x = random.choice([1, "foo"])將是合法的Python代碼 (歸功于?Ademan).?x的類型是什么? 我們?cè)趺赐瞥鲎兞康念愋?#xff0c;當(dāng)類型還沒有被嚴(yán)格實(shí)施?)通過RPython,你犧牲了一些靈活性, 但使得內(nèi)存管理和優(yōu)化大大的容易。
一個(gè)編譯RPython代碼為了各種目標(biāo)和加入及時(shí)編譯的編譯器。?默認(rèn)平臺(tái)是C,也就是從RPython到C編譯器,但你也可以瞄準(zhǔn)JVM或者其他。
只為清晰,我將引用這些PyPy(1)和PyPy(2)。
為什么你在同一層面下同時(shí)需要這兩者? 你可以這樣想一下:PyPy(1)是一個(gè)用RPython寫的解釋器,因此它能加載用戶的Python代碼并將它編譯成字節(jié)碼。但是這個(gè)用RPython寫的解釋器本身要能運(yùn)行,就必須要被另外一個(gè)Python實(shí)現(xiàn)去解釋,對(duì)不?
我們可以直接用CPython去運(yùn)行這個(gè)解釋器。但是這個(gè)還不夠快
取而代之,我們使用了PyPy(2)(參考?RPython的工具鏈)去編譯這個(gè)PyPy的解釋器,生成其他平臺(tái)(比如C, JVM或CLI)代碼在我們的機(jī)器上運(yùn)行,并且還加入了JIT特性。這個(gè)很神奇:PyPy動(dòng)態(tài)的將JIT加入一個(gè)解釋器,生成它自己編譯器!(這就是核心原理:我們?cè)诰幾g一個(gè)解釋器,并同時(shí)加入了另外一個(gè)單獨(dú)的編譯器到里面去)。
最終結(jié)果就是一個(gè)融合了JIT優(yōu)化特性的單獨(dú)的可執(zhí)行文件,用來解釋執(zhí)行我們的Python源代碼。這就是我們之前想要達(dá)到的效果。這么講可能比較拗口,下面這張圖可能會(huì)解釋的比較清楚點(diǎn):
再次重申下,PyPy真正可貴之處在于我們可以利用RPython實(shí)現(xiàn)各種不同的Python解釋器,不用去關(guān)心JIT(除了一些小的提示外)。PyPy到時(shí)候會(huì)利用RPython工具鏈/PyPy(2)為我們自動(dòng)實(shí)現(xiàn)JIT
事實(shí)上,我們還可以更抽象一點(diǎn),我們理論上可以寫一個(gè)適用于任何語言的解釋器,然后將它扔給PyPy,最后獲得那種語言的JIT。原因是PyPy僅僅關(guān)心的是優(yōu)化解釋器,而不會(huì)去關(guān)心這個(gè)解釋器到底解釋的是什么語言。
理論上你自己可以寫一個(gè)適用于任何語言的解釋器,然后將這個(gè)解釋器傳給PyPy,最后你得到這個(gè)語言的一個(gè)JIT。一個(gè)簡單的題外話,我這里想提一下,JIT本事是相當(dāng)棒的。它使用了一種叫做跟蹤的技術(shù),按照下面的步驟執(zhí)行:
想獲取更多信息,可以參考這篇文章,易于理解,并且非常有趣
最后收尾:我們使用PyPy的RPython-to-C(或者其他目標(biāo)平臺(tái))編譯器去編譯PyPy的基于RPython實(shí)現(xiàn)的解釋器。
結(jié)尾
為什么它如此的偉大?為什么這個(gè)瘋狂的想法值得我們?nèi)プ非?#xff1f;我想Alex Gaynor已經(jīng)在他的博客上面做了很好的解釋了:“[PyPy就是未來] 因?yàn)閇它]提供了更快的速度,更大的靈活性,并且對(duì)于Python的成長也提供了一個(gè)更好的平臺(tái)”
總之:
- 它很快,因?yàn)樗鼘⒃创a編譯成了本地機(jī)器碼(使用了JIT)
- 它很靈活,因?yàn)槌藰O少數(shù)的額外工作需要做外,它就能將JIT加入你的解釋器中
- 它還是很靈活,因?yàn)槟隳苁褂肦Python實(shí)現(xiàn)你的解釋器,這個(gè)比其他的(比如C語言)更易擴(kuò)展。事實(shí)上,它是如此的簡單,這里有一篇教程教你如何實(shí)現(xiàn)你自己的解釋器。
附錄: 其他一些你可能已經(jīng)聽過的名字
-
Python 3000 (Py3k): Python 3.0的一個(gè)別名,2008年釋出的一個(gè)主要版本,但是它并不向后兼容.。Py3k團(tuán)隊(duì)預(yù)測(cè)這個(gè)版本被完全采用可能需要5年時(shí)間.?,F(xiàn)在絕大多數(shù)(注意:這個(gè)是江湖傳聞)Python開發(fā)者繼續(xù)在使用2.x版本,不過現(xiàn)在人們?cè)絹碓蕉嗟膶?duì)Py3k開始關(guān)心了。
- Cython: 一個(gè)Python的超集,能夠調(diào)用C語言的函數(shù)
- 目標(biāo): 允許你為你的Python代碼寫C擴(kuò)展
- 允許你為你的Python代碼加入靜態(tài)類型,運(yùn)行編譯并達(dá)到接近C語言的性能。
- 這個(gè)跟PyPy比較類似,但是不是一樣的。使用這個(gè)的時(shí)候,在提交給編譯器之前必須用戶代碼里面寫好這些特殊代碼。如果使用PyPy的話,你寫的還是普通形式的Python代碼,編譯器會(huì)幫你處理一切優(yōu)化的工作。
-
Numba: 將JIT加入到被注解的Python代碼中,簡單來講就是,你給它一些提示,它就會(huì)優(yōu)化加速你這段代碼。Numba是Anaconda發(fā)行版(一系列數(shù)據(jù)分析和管理的軟件包)的一部分。
-
IPython: 跟我們討論過的其他版本完全不一樣。這是一個(gè)Python的計(jì)算環(huán)境。為一些GUI工具集和瀏覽器體驗(yàn)等提供支持。
- Psyco: 一個(gè)Python的擴(kuò)展模塊,也是早先的一種Python JIT的成果。?然而,它已經(jīng)被標(biāo)注為“停止維護(hù)和死亡”了。事實(shí)上,Psyco的首席開發(fā)者Armin Rigo現(xiàn)在在為PyPy工作。
語言綁定
-
RubyPython: Ruby和Python虛擬機(jī)的一座橋梁。允許你在你的Ruby代碼中嵌入Python代碼。你定義Python的起始位置,然后RubyPython負(fù)責(zé)在不同VM直接傳遞整理數(shù)據(jù)。
-
PyObjc: Python和Objective-C語言直接的橋梁。實(shí)際上,這意味著你能在你的Python代碼中使用Objective-C的庫(包括創(chuàng)建一個(gè)OS X應(yīng)用程序所需要的一切),反過來在Objective-C里面也可以使用Python的模塊。這樣的話,CPython用C語言來實(shí)現(xiàn)就很方便了,因?yàn)镃語言是Objective-C的一個(gè)子集。
-
PyQt: 同PyObjc幫你綁定OS X GUI組件類似,PyQt幫你綁定Qt應(yīng)用程序框架,讓你可以創(chuàng)建豐富的圖形界面,訪問關(guān)系數(shù)據(jù)庫等等。另外的一個(gè)旨在幫你簡化從Python到另外的框架的工具。?
JavaScript 框架
-
pyjs (Pyjamas): Python中一個(gè)創(chuàng)建web和桌面應(yīng)用程序的框架。包含一個(gè)Python-to-JavaScript的編譯器和其他一些工具。
-
Brython: 一個(gè)使用JavaScript語言寫的Python虛擬機(jī),可以讓Py2k 代碼在瀏覽器中執(zhí)行。
本文地址:http://www.oschina.net/translate/why-are-there-so-many-pythons
原文地址:http://www.toptal.com/python/why-are-there-so-many-pythons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
用以致學(xué),學(xué)以致用
轉(zhuǎn)載于:https://www.cnblogs.com/strive-man/p/8904495.html
總結(jié)
以上是生活随笔為你收集整理的为什么会有这么多python?其实python并不是编程语言!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot+shiro+red
- 下一篇: mysql连接com.mysql.jdb