python解釋器
計算機編程語言
本部分參考自:https://zhuanlan.zhihu.com/p/141212114
從計算機編程語言說起,它主要分為三類:機器語言、匯編語言、高級語言。
機器語言是一種計算機可以直接識別并執行的二進制指令集。由于其可以直接交給CPU執行,所以是最快的,但是它需要我們記住每一個指令的代碼與對應的動作,想想我們寫代碼的時候是操作一串串的01序列,難度得有多大。
為了克服機器語言的缺點,人們就用一些助記符來代替機器碼,也就是使用一些與實際意義相近的縮略詞來代替動作,例如ADD、SUB、MOV等,這就有了很大的進步,可以方便的編寫,但是它仍然是對機器進行操作的,相較于高級程序語言更接近于底層,所以匯編語言是低級語言。
不論是機器語言還是匯編語言都是面向硬件的操作,它們對于機器是依賴的,不同的設備對應的編寫方式可能不同。然而,高級語言是面向用戶的語言,我們只要編寫好程序內容,通過編譯或者解釋程序,就可以對機器進行操作。這里提到的編譯或者解釋程序就是一個翻譯工具,將人類看懂的語言翻譯成機器能看懂的東西。
解釋型語言VS編譯型語言
解釋型語言和編譯型語言的共同目標都是為了將我們所認識的語句(例如循環、判斷)轉成二進制代碼,再交給計算機執行。
二者之間最明顯的區別,編譯型語言就是指在我們把程序寫完之后,把代碼完全翻譯成二進制文件,通過執行該二進制文件來執行程序;而解釋型語言沒有轉二進制文件的過程,而是什么時候需要,什么時候編譯。有人說,這算什么區別呢?還沒有說完,編譯型語言生成二進制文件后,那這個二進制文件就可以直接執行,而解釋型語言需要隨時帶著這個解釋器,必須隨叫隨到。因此、產生了各種方面的差異,以下是我所理解的較為明顯的差異。
運行速度 | 可移植性(跨平臺) | 更新 | 安全 | |
---|---|---|---|---|
編譯型語言 | 快(二進制文件) | 差(CPU指令系統變則執行出錯) | 重新編譯 | 好(無需提供源碼) |
解釋型語言 | 慢(邊解釋邊執行) | 好(隨身帶著解釋器) | 僅解釋更新的內容 | 差(連同源碼一起交付) |
Python解釋器
有了上面的描述,想必知道解釋器是怎么回事了。解釋器其實也包括編譯過程,只是這個編譯過程沒有生成目標代碼。Python解釋器由編譯器和虛擬機構成,編譯器將源代碼轉換成字節碼,然后再通過Python虛擬機來逐行執行這些字節碼。
python程序執行過程:
1、執行 .py 文件,就會啟動python解釋器
2、編譯器將源文件解釋成字節碼
3、虛擬機將字節碼轉化成機器語言,與操作系統交互
4、程序運行結束后,將字節碼存到pyc文件,便于后續直接執行
python解釋器種類
本部分參考自:https://www.liaoxuefeng.com/wiki/1016959663602400/1016966024263840
當我們編寫Python代碼時,我們得到的是一個包含Python代碼的以.py
為擴展名的文本文件。要運行代碼,就需要Python解釋器去執行.py
文件。
由于整個Python語言從規范到解釋器都是開源的,所以理論上,只要水平夠高,任何人都可以編寫Python解釋器來執行Python代碼(當然難度很大)。事實上,確實存在多種Python解釋器。
-
CPython 當我們從Python官方網站下載并安裝好Python 3.x后,我們就直接獲得了一個官方版本的解釋器:CPython。這個解釋器是用C語言開發的,所以叫CPython。在命令行下運行
python
就是啟動CPython解釋器。CPython是使用最廣的Python解釋器。 -
IPython IPython是基于CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的。好比很多國產瀏覽器雖然外觀不同,但內核其實都是調用了IE。
CPython用
>>>
作為提示符,而IPython用In [序號]:
作為提示符。 -
PyPy PyPy是另一個Python解釋器,它的目標是執行速度。PyPy采用JIT技術,對Python代碼進行動態編譯(注意不是解釋),所以可以顯著提高Python代碼的執行速度。絕大部分Python代碼都可以在PyPy下運行,但是PyPy和CPython有一些是不同的,這就導致相同的Python代碼在兩種解釋器下執行可能會有不同的結果。如果你的代碼要放到PyPy下執行,就需要了解PyPy和CPython的不同點。
-
Jython Jython是運行在Java平臺上的Python解釋器,可以直接把Python代碼編譯成Java字節碼執行。
-
IronPython IronPython和Jython類似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,可以直接把Python代碼編譯成.Net的字節碼。
Python的解釋器很多,但使用最廣泛的還是CPython。如果要和Java或.Net平臺交互,最好的辦法不是用Jython或IronPython,而是通過網絡調用來交互,確保各程序之間的獨立性。
python解釋器與java虛擬機
本部分參考自:https://zhuanlan.zhihu.com/p/58167547
看到Stackoverflow上有個問題在討論Java和Python的對比,其中就有人問答為啥Java的運行環境被稱之為JVM,而Python的只能叫做Interpreter。
這個問題估計想過的人不多,先找維基百科看一下虛擬機的定義。
虛擬機的定義有2個,一種是類似Vmware的系統虛擬機,另一種是虛擬機稱之為程序虛擬機,諸如JVM,CLR就是最常見到的虛擬機。
程序虛擬機也稱作托管運行時環境,運行這個虛擬機時,就好比普通的OS中的一個進程。當這個進程啟動時,虛擬機啟動,當進程銷毀時,虛擬機銷毀。使用虛擬機的目的就是提供一個和平臺無關的編程環境。
JVM中的執行引擎只能處理編譯后的Java字節碼,字節碼處理引擎其實包含一個字節碼解釋器和一個JIT編譯器(和.net的CLR中JIT差別很大),解釋器逐條的執行字節碼指令,速度稍慢。JIT編譯器則會將熱點代碼編譯緩存起來,因此執行速度加快。
解釋器的概念比較簡單,它可以將代碼翻譯,并運行,不需要經過編譯,JVM中的解釋器正式這樣的,JVM中解釋的就是字節碼。解釋器運行程序的方法有3種:
- 直接運行高級編程語言(如Shell內置的解釋器)
- 轉換高級編程語言碼到一些有效率的字節碼(Bytecode),并運行這些字節碼
- 以解釋器包含的編譯器對高級語言編譯,并指示處理器運行編譯后的程序(例如:JIT)
其中Python的解釋器就是屬于第二種,Python代碼在首次運行時,它會將Python代碼編譯成字節碼,如果可以的話,它會將這個字節碼保存到.pyc文件中,這樣下次啟動的時候就不會再編譯這些代碼而是直接解釋運行字節碼。事實上,這種機制正在模糊解釋器和編譯器之間的界限,或者說是模糊了解釋型語言和編譯型語言的界限。
通過JVM和解釋器的概念澄清,似乎還是不明白為啥JVM就被稱為虛擬機,JVM中有運行的是字節碼,它可能直接被解釋執行,也可能被再次編譯成目標語言,Python中的解釋器也會先預編譯Python代碼為字節碼,再解釋執行。那么到底有啥區別?
很多人參與了討論,分別從不同的角度去闡述區別。
有人認為虛擬機是和語言無關的,JVM為例,除了Java之外,Scala,Clojure,甚至Python借助于Jython工具,也可以運行在JVM上,而沒聽說什么語言能有Python解釋器解釋執行,除了Python。
也有人從語言的類型上,Java為靜態類型的語言,而Python為動態語言。這使得Java字節碼既可以被解釋執行也可以被編譯成機器指令再執行。而Python則復雜多了,它雖然讓程序員可以不去關注變量的類型,但解釋器不得不去推斷數據類型,這一定程度上影響性能。
還有觀點認為解釋器是一個歷史遺留術語,現代語言中虛擬機和解釋器的分界已經很模糊甚至不存在。
事實上,在《Learning Python》一書中,作者把Python的解釋器稱為PVM。PVM是一個棧結構虛擬機(這里虛擬機分為基于棧的和基于寄存器的),它把字節碼中的指令一條條執行過來就行。不用轉換字節碼。基于這個事實來講,可以認為解釋器和虛擬機的區別正在越來越小,已經是我中有你,你中有我的地步。獨立的分割來看,可能還能區分這幾步是解釋器行為,這幾步是虛擬機的行為,但是作為一個整體來看,兩者的區別確實沒那么明顯。