Python?Python!(python是解释型还是编译型)
文章目錄
- 解釋型語言?編譯型語言?
- 1. 為什么要有解釋型語言?
- 2. `.pyc`文件
- 3 對于python是解釋型還是編譯型的判斷
- 3.1 字節碼和機器語言的區別
- 3.2 解釋器和虛擬機
- 4. 為什么要有解釋型語言?(個人拙見)
前言:一個人,閑著沒事,就喜歡胡思亂想,這一想就想出了很多東西,因此就充滿了疑問,這又是一個百度的下午。看了很多篇博文,思路始終很是凌亂,不知道怎么寫,有些內容看完就忘記了,但是我還是要進自己最大的努力去把下午看過的內容進行總結,這樣也不枉費這一下午百度的流量。如果您和我一樣,對python的運行有一些疑惑那么請您仔細閱讀這篇文章,我寫了很久,雖然我不能保證看完您就對python底層的運行機制徹底了解,但是應該也會有一個大體的流程,大致的框架。
解釋型語言?編譯型語言?
相信很多初學python的人都被告知python是一種解釋性語言。那么我們要思考的第一個問題就是
什么是解釋型語言?什么是編譯型語言?python到底是解釋型還是編譯型?
-
編譯器
計算機不能直接理解任何除機器語言以外的語言,所以必須要把程序員所寫的程序語言翻譯成機器語言,計算機才能執行程序。將其他語言翻譯成機器語言的工具,被稱為編譯器。
編譯器翻譯的方式有兩種:一個是編譯,一個是解釋。兩種方式之間的區別在于翻譯時間點的不同。當編譯器以解釋方式運行的時候,也稱之為解釋器。
-
解釋型語言:
解釋型語言,是在運行的時候將程序翻譯成機器語言。
解釋型語言的程序不需要在運行前編譯,在運行程序的時候才翻譯,專門的解釋器負責在每個語句執行的時候解釋程序代碼。這樣解釋型語言每執行一次就要翻譯一次,效率比較低。
通俗一點講就是:由于計算機底層不能識別高級語言,因此我們寫的代碼需要被翻譯成機器語言給計算機硬件,他們拿到機器語言后才能執行相關的操作;而解釋性語言的原理就是翻譯的時候,是逐行翻譯的,也就是把你寫的代碼一行一行的翻譯給機器,然后機器再執行;如果再次運行的話也是如此,機器不會因為執行過這個代碼就會有所記憶,他依然需要解釋器來為他逐行翻譯代碼。
-
編譯型語言:
編譯型語言的首先將源代碼編譯生成機器語言,再由機器運行機器碼(二進制)
程序在執行之前需要一個專門的編譯過程,把程序編譯成 為機器語言的文件,運行時不需要重新翻譯,直接使用編譯的結果就行了。
也就是編譯器一口氣將整個代碼全部翻譯成了機器語言,然后交給底層設備去執行。
-
解釋型和編譯型的區別
我們這么設想一個場景:
現在有一個老板(高級語言),一個翻譯(編譯器),一個外國工人(計算機硬件)。老板想讓工人按照自己的想法做一個產品,但是老板不會說外語,因此需要翻譯將老板的想法告訴工人。
那么就有兩種翻譯方式:
- 解釋型翻譯
老板說一句,翻譯翻譯一句給工人,工人執行一步。 - 編譯型翻譯
翻譯將老板的所有想法翻譯好成一個文本,然后交給工人,工人拿著文本看完開始干活。
1. 為什么要有解釋型語言?
既然編譯型語言速度更優,要求更低,那么為何還會有解釋型語言的產生?
在這里,我們先不討論為什么會有解釋型語言的產生,我們先來看今天我引發這一系列問題的導火索—>.pyc文件。
2. .pyc文件
今天閑著沒事干突然覺得,python文件中有一個__pycache__好不順眼,就點開看了看,一看就是一下午:
我們發現在這里面竟然藏著一個test1.cpython-37.pyc。我很好奇,這是個啥?為啥只有test1的?test2呢?通過字面意思我們大概知道這個文件夾是一個python緩存文件夾,而.pyc是一個complied文件。
沒錯,這是一個complied類型的文件。當時我就懵了,說好的解釋型語言呢?關鍵是這玩意打也打不開,用記事本打開還是亂碼。(什么?不相信?不信就看看!)
這玩意誰能看懂?如果有能看懂的就請滑倒屏幕最下方點個贊然后走吧!
繼續正文啊,這東西,一看就不是個正常的東西,那不正常的東西一定要用不一般的軟件給他破了。
嗯,雖然這次我還是看不懂,但是他最起碼看起來正常點了。對吧!
通過查閱資料,我知道這個pyc文件大有來頭。
首先,這個東西他不是隨隨便便就有的,他的出現,有他出現的道理:
我們先看兩張圖:
我這么多python代碼,才有兩個有pyc文件,看著爆率多么低,至少也是ssr級別的。
可是這樣就更懵了有木有,說好的解釋型語言,突然蹦出來一個編譯文件,完了還是憑概率給你beng出來。你以為玩游戲抽獎呢?
那么接下來我們就來解開pyc的神秘面紗!
首先我們來看一下產生pyc文件的條件:
那么.pyc這個東西是干什么用的呢?
在說這個問題之前,我們先來說兩個概念,PyCodeObject和pyc文件。
對于Python編譯器來說,PyCodeObject對象是其真正的編譯結果,它存儲在內存中,而pyc文件只是這個對象在硬盤上的表現形式。
在python程序運行期間,編譯的結果是保存在位于內存中的PyCodeObject中,當Python程序運行結束時,Python解釋器則將PyCodeObject寫回到pyc文件中。
當python程序第二次運行時,首先程序會在硬盤中尋找pyc文件,如果找到,先對.pyc文件和.py文件的最近一次的修改時間進行判斷,如果.pyc文件的修改時間晚于.py文件,說明.py文件中的源代碼未修改過,則Python會根據pyc文件中記錄的編譯結果直接建立內存中PyCodeObject對象,而不用再次對源碼進行編譯了,否則就重復上面的過程。而把py文件的編譯結果保存到pyc文件,最大的優點在于在運行程序時,不需要對該源碼重新進行編譯。
所以我們應該這樣來定位PyCodeObject和pyc文件,我們說pyc文件其實是PyCodeObject的一種持久化保存方式。
因此我們知道,.pyc就像是一個緩存,便于我們下次使用的時候能夠提取的更快。
3 對于python是解釋型還是編譯型的判斷
那么,通過上面兩千多字的描述,我們大概知道了,哦,原來python再被執行的時候,可能會被編譯成.pyc文件。那么,為什么要稱他為解釋型語言?他既然有了編譯成.pyc的這個過程(盡管不是一定會有),那么說他是解釋型語言是不是有點勉強?
此時,我們再來看一下,百度百科給編譯型語言的定義:
運行編譯型語言是相對于解釋型語言存在的,編譯型語言的首先將源代碼編譯生成機器語言,再由機器運行機器碼(二進制)
這里要對首先將源代碼編譯生成機器語言劃重點。編譯型語言是直接將高級語言翻譯成為了機器語言。而我們的python是么?當然不是,我們的python是將高級語言翻譯成了字節碼。那么問題又來了?字節碼和機器語言是一個東西么?
3.1 字節碼和機器語言的區別
-
機器語言
這里先給出百度百科的定義:機器語言是機器能直接識別的程序語言或指令代碼,勿需經過翻譯,每一操作碼在計算機內部都有相應的電路來完成它,或指不經翻譯即可為機器直接理解和接受的程序語言或指令代碼。
簡單來說就是機器語言是我們底層設備直接能讀懂的語言。
-
字節碼
字節碼(Byte-code)是一種包含執行程序,由一序列 op 代碼/數據對組成的二進制文件,是一種中間碼。字節是電腦里的數據量單位。
字節碼,我們的底層設備是看不懂的,他需要被進一步翻譯成機器語言才行。字節碼主要為了實現和軟件環境、與硬件環境無關的特定軟件的運行。字節碼的實現方式是通過編譯器和虛擬機器。編譯器將源碼編譯成字節碼,特定平臺上的虛擬機器將字節碼轉譯為可以直接執行的指令。
字節碼是一種中間碼,需要被虛擬機進一步翻譯成為機器語言。
簡書的一篇博文中有一張圖片可以參考一下,來了解這個過程:
3.2 解釋器和虛擬機
那么在談到機器語言和字節碼,我們又不得不提到python解釋器和python虛擬機。
-
python解釋器
首先我們來談談python解釋器:
大家應該都知道cpython,1991年,第一個Python編譯器(同時也是解釋器)誕生。它是用C語言實現的,并能夠調用C庫(.so文件)。從一出生,Python已經具有了:類(class),函數(function),異常處理(exception),包括列表(list)和字典(dictionary)在內的核心數據類型,以及模塊(module)為基礎的拓展系統。當我們從Python官方網站下載并安裝好Python后,我們就直接獲得了一個官方版本的解釋器:CPython。這個解釋器是用C語言開發的,所以叫CPython。在命令行下運行python就是啟動CPython解釋器。
當然除了cpython以外,還有基于java的jpython,基于python的pypy等等。
那么我們的python解釋器的作用就是將我們的高級語言翻譯成字節碼。也就是.pyc文件。
-
虛擬機
注意:虛擬機的定義有2個,一種是類似Vmware的系統虛擬機,另一種是虛擬機稱之為程序虛擬機。而我們這里談到的就是第二種–程序虛擬機。而在這里我們的程序虛擬機的主要作用就是將解釋器編譯的字節碼翻譯成為機器能夠識別的機器語言。
那么我們就知道了,我們的python需要先通過python解釋器將代碼翻譯成為字節碼,然后在通過虛擬機將字節碼翻譯為機器碼。此時,我們的的機器才能夠執行這些指令。
那么到此為止,我們在回頭想我們的問題—python到底是解釋型語言還是編譯型語言?
我個人覺得,這要看如何定義了。
如果按照百度百科的定義:
運行編譯型語言是相對于解釋型語言存在的,編譯型語言的首先將源代碼編譯生成機器語言,再由機器運行機器碼(二進制)
我們又一次把他請出來了!我們注意到將源代碼編譯生成機器語言。
因此這里對編譯型語言的定義可能就是:直接將原碼編譯為機器語言。
而我們的python是先將原碼編譯為字節碼,然后將字節碼翻譯為機器語言。
因此,python對于此定義來將可能不屬于編譯型語言的范疇。
如果另有一種定義說編譯型語言就是先將高級語言轉換為比他自己低級的語言。那么python可能就又屬于編譯型語言了。(但是好像并沒有這種定義)
因此,我們就知道了為什么python是解釋型語言而不是編譯型語言了。
4. 為什么要有解釋型語言?(個人拙見)
可能讀者注意到這個標題我之前已經寫過了,但是并未給出一個結論。因為我在前言說過,寫這篇文章的時候,因為信息量對我來說很大,而且很難整理,我的思路也有些亂,而且剛開始拋出這個問題就是為了引出以上三個問題,我覺得只有先知道了解釋型語言和編譯型語言的區別、字節碼和機器語言的區別以及解釋器和虛擬機的作用才能夠更深的理解解釋型語言的原理,更好的理解為什么要有解釋型語言和編譯型原因的區別。那么對于解釋型語言的存在可能自己的心中也會有一些自己的想法。如果讀者們覺得這個排版不好也請見諒,因為我是按照自己的思路來寫的。
那么回歸正題,為什要有解釋型語言?
關于這個問題的答案我沒有去查資料,我個人覺得像這么一個已經被普遍使用的東西被發明出來,肯定是有很多需求的。
雖然編譯型語言的速度較優,對于機器的要求也比較低,但是他的跨平臺性不好。也就是說如果你在windows下編譯了一個c,如果把這個編譯文件弄到linux下去運行是不行的。因此linux和windows對于機器碼的識別是不同的。但是作為解釋型語言的python則完成了跨平臺的完美銜接。我們知道python是先被編譯為字節碼。而對于字節碼來講,無論是windows還是linux,各自平臺上的虛擬機都能夠識別這個字節碼,并且翻譯為自己底層機器可能識別的機器碼。因此,你用python編寫的腳本是可以跨平臺使用的。
當然,解釋型語言肯定還有很多其他需要的原因而被發明。上面這個觀點也只是我個人的拙見。因為我的知識儲備不夠,所以也說不出來更深層次的原因。
到這里文章就結束了,在最后我把我參考的一些資料放在下面,意猶未盡的讀者們可以看一下:
python是解釋型語言么?
python是解釋型語言么?
機器碼和字節碼
python虛擬機的運行原理
python是用c寫的嗎
python虛擬機是什么
什么是cpython
解釋型語言
編譯型語言
python解釋器詳解
總結
以上是生活随笔為你收集整理的Python?Python!(python是解释型还是编译型)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生产者消费者模式详解(转载)
- 下一篇: 用python绘制漂亮的图形