Python程式設計基礎(一)程式語言是什麼?編譯型語言和解釋型語言的區別|Python是什麼?
程式語言是什麼?
其實,程式指的就是一系列指令,用來告訴計算機做什麼,而編寫程式的關鍵在於,我們需要用計算機可以理解的語言來提供這些指令。
雖然藉助 Siri(Apple)、Google Now(Android)、Cortana(Microsoft)等技術,我們可以使用漢語直接告訴計算機做什麼,比如“Siri,開啟酷狗音樂”,但使用過這些系統的讀者都知道,它尚未完全成熟,再加上我們語言充滿了模糊和不精確因素,使得設計一個完全理解人類語言的計算機程式,仍然是一個有待解決的問題。
為了有效避開所有影響給計算機傳遞指令的因素,電腦科學家設計了一些符號,這些符號各有其含義,且之間無二義性,通常被它們為程式語言。程式語言中的每個結構,都有固定的使用格式(稱為語法)以及精確的含義(稱為語義)。換句話說,程式語言指定了成套的規則,用來編寫計算機可以理解的指令。習慣上,我們將這一條條指令稱為計算機程式碼,而用程式語言來編寫演算法的過程稱為編碼。
本教程要講解的 Python 就是一種程式語言,除此之外,你肯定也聽說過其他一些程式語言,如 C、C++、Java、Ruby 等。至今,電腦科學家已經開發了成百上千種程式語言,且隨著時間演變,這些程式語言又產生了多個不同的版本。但無論是哪個程式語言,也無論有多少個版本,雖然它們在細節上可能有所不同,無疑它們都有著固定的、無二義性的語法和語義。
以上提到的程式語言,都是高階計算機語言,設計它們的目的是為了方便程式設計師理解和使用。但嚴格來說,計算機硬體只能理解一種非常低階的程式語言,稱為機器語言。
比如說,讓計算機對 2 個數做求和操作,那麼 CPU 可能要執行以下指令:
- 將位於記憶體空間位置在 2001 的數載入到 CPU 中;
- 再將位於記憶體空間位置在 2002 的數也載入到 CPU中;
- 在 CPU中,對這 2 個數做求和操作;
- 將結果儲存在位置為 2003 的記憶體空間。
可以看到,對 2 個數執行求和操作需要做這麼多工作,且這還只是籠統地描述,實際會更加複雜。
而使用 Python 這樣的高階語言,對 2 個數求和可以很自然地用 c = a + b 表示,但由此帶來的問題是,我們需要設計一種方法,將高階語言翻譯成計算機可以執行的機器語言,有兩種方法可以實現,分別是使用編譯器和直譯器。
使用編譯器將自身等效轉換成機器語言的高階語言,通常稱為編譯型語言;而使用直譯器將自身轉換成機器語言的高階語言,稱為解釋型語言,Python 就是解釋型程式語言的一種。
編譯型語言和解釋型語言的區別
我們編寫的原始碼是人類語言,我們自己能夠輕鬆理解;但是對於計算機硬體(CPU),原始碼就是天書,根本無法執行,計算機只能識別某些特定的二進位制指令,在程式真正執行之前必須將原始碼轉換成二進位制指令。
所謂的二進位制指令,也就是機器碼,是 CPU 能夠識別的硬體層面的“程式碼”,簡陋的硬體(比如古老的微控制器)只能使用幾十個指令,強大的硬體(PC 和智慧手機)能使用成百上千個指令。
然而,究竟在什麼時候將原始碼轉換成二進位制指令呢?不同的程式語言有不同的規定:
- 有的程式語言要求必須提前將所有原始碼一次性轉換成二進位制指令,也就是生成一個可執行程式(Windows 下的 .exe),比如C語言、C++、Golang、Pascal(Delphi)、彙編等,這種程式語言稱為編譯型語言,使用的轉換工具稱為編譯器。
- 有的程式語言可以一邊執行一邊轉換,需要哪些原始碼就轉換哪些原始碼,不會生成可執行程式,比如 Python、JavaScript、PHP、Shell、MATLAB 等,這種程式語言稱為解釋型語言,使用的轉換工具稱為直譯器。
簡單理解,編譯器就是一個“翻譯工具”,類似於將中文翻譯成英文、將英文翻譯成俄文。但是,翻譯原始碼是一個複雜的過程,大致包括詞法分析、語法分析、語義分析、效能優化、生成可執行檔案等五個步驟,期間涉及到複雜的演算法和硬體架構。直譯器與此類似,有興趣的讀者請參考《編譯原理》一書,本文不再贅述。
Java 和 C# 是一種比較奇葩的存在,它們是半編譯半解釋型的語言,原始碼需要先轉換成一種中間檔案(位元組碼檔案),然後再將中間檔案拿到虛擬機器中執行。Java 引領了這種風潮,它的初衷是在跨平臺的同時兼顧執行效率;C# 是後來的跟隨者,但是 C# 一直止步於 Windows 平臺,在其它平臺鮮有作為。
圖 1 編譯型語言和解釋型語言的執行流程
那麼,編譯型語言和解釋型語言各有什麼特點呢?它們之間有什麼區別?
編譯型語言
對於編譯型語言,開發完成以後需要將所有的原始碼都轉換成可執行程式,比如 Windows 下的.exe
檔案,可執行程式裡面包含的就是機器碼。只要我們擁有可執行程式,就可以隨時執行,不用再重新編譯了,也就是“一次編譯,無限次執行”。
在執行的時候,我們只需要編譯生成的可執行程式,不再需要原始碼和編譯器了,所以說編譯型語言可以脫離開發環境執行。
編譯型語言一般是不能跨平臺的,也就是不能在不同的作業系統之間隨意切換。
編譯型語言不能跨平臺表現在兩個方面:
(1) 可執行程式不能跨平臺
可執行程式不能跨平臺很容易理解,因為不同作業系統對可執行檔案的內部結構有著截然不同的要求,彼此之間也不能相容。不能跨平臺是天經地義,能跨平臺反而才是奇葩。
比如,不能將 Windows 下的可執行程式拿到 Linux 下使用,也不能將 Linux 下的可執行程式拿到 Mac OS 下使用(雖然它們都是類 Unix 系統)。
另外,相同作業系統的不同版本之間也不一定相容,比如不能將 x64 程式(Windows 64 位程式)拿到 x86 平臺(Windows 32 位平臺)下執行。但是反之一般可行,因為 64 位 Windows 對 32 位程式作了很好的相容性處理。
(2) 原始碼不能跨平臺
不同平臺支援的函式、型別、變數等都可能不同,基於某個平臺編寫的原始碼一般不能拿到另一個平臺下編譯。我們以C語言為例來說明。
【例項1】在C語言中要想讓程式暫停可以使用“睡眠”函式,在 Windows 平臺下該函式是 Sleep(),在 Linux 平臺下該函式是 sleep(),首字母大小寫不同。其次,Sleep() 的引數是毫秒,sleep() 的引數是秒,單位也不一樣。
以上兩個原因導致使用暫停功能的C語言程式不能跨平臺,除非在程式碼層面做出相容性處理,非常麻煩。
【例項2】雖然不同平臺的C語言都支援 long 型別,但是不同平臺的 long 的長度卻不同,例如,Windows 64 位平臺下的 long 佔用 4 個位元組,Linux 64 位平臺下的 long 佔用 8 個位元組。
我們在 Linux 64 位平臺下編寫程式碼時,將 0x2f1e4ad23 賦值給 long 型別的變數是完全沒有問題的,但是這樣的賦值在 Windows 平臺下就會導致數值溢位,讓程式產生錯誤的執行結果。
讓人苦惱的,這樣的錯誤一般不容易察覺,因為編譯器不會報錯,我們也記不住不同型別的取值範圍。
解釋型語言
對於解釋型語言,每次執行程式都需要一邊轉換一邊執行,用到哪些原始碼就將哪些原始碼轉換成機器碼,用不到的不進行任何處理。每次執行程式時可能使用不同的功能,這個時候需要轉換的原始碼也不一樣。
因為每次執行程式都需要重新轉換原始碼,所以解釋型語言的執行效率天生就低於編譯型語言,甚至存在數量級的差距。計算機的一些底層功能,或者關鍵演算法,一般都使用 C/C++ 實現,只有在應用層面(比如網站開發、批處理、小工具等)才會使用解釋型語言。
在執行解釋型語言的時候,我們始終都需要原始碼和直譯器,所以說它無法脫離開發環境。
當我們說“下載一個程式(軟體)”時,不同型別的語言有不同的含義:
- 對於編譯型語言,我們下載到的是可執行檔案,原始碼被作者保留,所以編譯型語言的程式一般是閉源的。
- 對於解釋型語言,我們下載到的是所有的原始碼,因為作者不給原始碼就沒法執行,所以解釋型語言的程式一般是開源的。
相比於編譯型語言,解釋型語言幾乎都能跨平臺,“一次編寫,到處執行”是真是存在的,而且比比皆是。那麼,為什麼解釋型語言就能快平臺呢?
這一切都要歸功於直譯器!
我們所說的跨平臺,是指原始碼跨平臺,而不是直譯器跨平臺。直譯器用來將原始碼轉換成機器碼,它就是一個可執行程式,是絕對不能跨平臺的。
官方需要針對不同的平臺開發不同的直譯器,這些直譯器必須要能夠遵守同樣的語法,識別同樣的函式,完成同樣的功能,只有這樣,同樣的程式碼在不同平臺的執行結果才是相同的。
你看,解釋型語言之所以能夠跨平臺,是因為有了直譯器這個中間層。在不同的平臺下,直譯器會將相同的原始碼轉換成不同的機器碼,直譯器幫助我們遮蔽了不同平臺之間的差異。
關於 Python
Python 屬於典型的解釋型語言,所以執行 Python 程式需要直譯器的支援,只要你在不同的平臺安裝了不同的直譯器,你的程式碼就可以隨時執行,不用擔心任何相容性問題,真正的“一次編寫,到處執行”。
Python 幾乎支援所有常見的平臺,比如 Linux、Windows、Mac OS、Android、FreeBSD、Solaris、PocketPC 等,你所寫的 Python 程式碼無需修改就能在這些平臺上正確執行。也就是說,Python 的可移植性是很強的。
總結
我們將編譯型語言和解釋型語言的差異總結為下表:
型別 | 原理 | 優點 | 缺點 |
---|---|---|---|
編譯型語言 | 通過專門的編譯器,將所有原始碼一次性轉換成特定平臺(Windows、Linux 等)執行的機器碼(以可執行檔案的形式存在)。 | 編譯一次後,脫離了編譯器也可以執行,並且執行效率高。 | 可移植性差,不夠靈活。 |
解釋型語言 | 由專門的直譯器,根據需要將部分原始碼臨時轉換成特定平臺的機器碼。 | 跨平臺性好,通過不同的直譯器,將相同的原始碼解釋成不同平臺下的機器碼。 | 一邊執行一邊轉換,效率很低。 |
Python是什麼?
程式語言有“高低”之分,而高階語言又有很多種,比如 C++、Java、C#、PHP、JavaScript 等,Python 也是其中之一。從本節開始,我們將正式開始學習 Python 這門高階程式語言,但是在此之前,我們有必要先討論一下“Python 是什麼”。
Python 英文原意為“蟒蛇”,直到 1989 年荷蘭人 Guido van Rossum (簡稱 Guido)發明了一種面向物件的解釋型程式語言,並將其命名為 Python,才賦予了它表示一門程式語言的含義。
而在上文我們已經解釋了什麼是解釋型程式語言。
說道 Python,它的誕生是極具戲曲性的,據 Guido 的自述記載,Python 語言是他在聖誕節期間為了打發時間開發出來的,之所以會選擇 Python 作為該程式語言的名字,是因為他是一個叫 Monty Python 戲劇團體的忠實粉絲。
Python 語言是在 ABC 教學語言的基礎上發展來的;遺憾的是,ABC 語言雖然非常強大,但卻沒有普及應用,Guido 認為是它不開放導致的。
基於這個考慮,Guido 在開發 Python 時,不僅為其添加了很多 ABC 沒有的功能,還為其設計了各種豐富而強大的庫,利用這些 Python 庫,程式設計師可以把使用其它語言製作的各種模組(尤其是C語言和 C++)很輕鬆地聯結在一起,因此 Python 又常被稱為“膠水”語言。
這裡的庫和模組,簡單理解就是一個個的原始檔,每個檔案中都包含可實現各種功能的方法(也可稱為函式)。
從整體上看,Python 語言最大的特點就是簡單,該特點主要體現在以下 2 個方面:
- Python 語言的語法非常簡潔明瞭,即便是非軟體專業的初學者,也很容易上手。
- 和其它程式語言相比,實現同一個功能,Python 語言的實現程式碼往往是最短的。
對於 Python,網路上流傳著“人生苦短,我用 Python”的說法。
因此,看似 Python 是“不經意間”開發出來的,但絲毫不比其它程式語言差。事實也是如此,自 1991 年 Python 第一個公開發行版問世後:
- 2004 年起 Python 的使用率呈線性增長,不斷受到程式設計者的歡迎和喜愛;
- 2010 年,Python 榮膺 TIOBE 2010 年度語言桂冠;
- 2017 年,IEEE Spectrum 釋出的 2017 年度程式語言排行榜中,Python 位居第 1 位。
直至現在(2019 年 12 月份),根據 TIOBE 排行榜的顯示,Python 也居於第 3 位,且有繼續提升的態勢(如下圖表示)。
2019年12月 | 2018年12月 | 程式語言 | 市場份額 | 變化 |
---|---|---|---|---|
1 | 1 | Java | 17.253% | +1.32% |
2 | 2 | C | 16.086% | +1.80% |
3 | 3 | Python | 10.308% | +1.93% |
4 | 4 | C++ | 6.196% | -1.37% |
5 | 6 | C# | 4.801% | +1.35% |
6 | 5 | Visual Basic .NET | 4.743% | -2.38% |
7 | 7 | JavaScript | 2.090% | -0.97% |
8 | 8 | PHP | 2.048% | -0.39% |
9 | 9 | SQL | 1.843% | -0.34% |
10 | 14 | Swift | 1.490% | +0.27% |
11 | 17 | Ruby | 1.314% | +0.21% |
12 | 11 | Delphi/Object Pascal | 1.280% | -0.12% |
13 | 10 | Objective-C | 1.204% | -0.27% |
14 | 12 | Assembly language | 1.067% | -0.30% |
15 | 15 | Go | 0.995% | -0.19% |
16 | 16 | R | 0.995% | -0.12% |
17 | 13 | MATLAB | 0.986% | -0.30% |
18 | 25 | D | 0.930% | +0.42% |
19 | 19 | Visual Basic | 0.929% | -0.05% |
20 | 18 | Perl | 0.899% | -0.11% |
顯然,Python 已經將 C++ 語言甩在了後邊,直逼 C 語言和 Java,而且未來有可能超越它們,成為程式語言排行榜冠軍。
我們不妨再看一下 Python 歷年來的市場份額變化曲線,Python 的未來大勢可期。
Python 歷年來市場份額變化曲線
錯過了 C/C++ 的 PC 時代,又錯過了 Java 的網際網路和智慧手機時代,你還想錯過 Python 的人工智慧和大資料時代嗎?Python 正位於軟體產業的第四次風口之上,把握好風口,你就能飛起來。
想學習Python的朋友可以檢視一下我往期的文章,有許多書籍及教程,都是可以直接下載