文章出處

本節內容


  1. Python簡史
  2. Python是一門什么樣的語言?
  3. Python的優點與缺點
  4. Python解釋器

一、Python簡史


歷史背景

在20世紀80年代,IBM和蘋果已經掀起了個人電腦的浪潮。但是在今天看來,當時的個人電腦的配置都很低,以至于一個大的數組就能把內存占滿。為了讓程序能夠運行,當時所有編程語言編譯器的核心就是盡量的去做優化。為了提高程序運行效率,編程語言迫使程序員去像計算機一樣思考,以便寫出更符合計算機口味的程序。在那個時代,程序猿生活在水深火熱之中,他們被迫去像資本家一樣花費大量的時間和精力想盡一切辦法去榨干計算機的每一寸能力。

Guido von Rossum,一個擁有阿姆斯特丹大學數學和計算機碩士雙學位的荷蘭人,他當時也是一個苦逼程序猿,并且他已經接觸并使用過C語言。當時Guido面臨的現狀是:即使他已經準確的知道了如何用C語言去寫出一個功能,整個編寫過程還是需要耗費大量的時間,因為他要考慮“這樣寫計算機是不是喜歡”。這讓Guido感到非常苦惱。Guido的另外一個選擇是使用shell。Boure Shell 作為UNIX系統的解釋器(interpreter)已經長期存在。UNIX的管理員們常常用shell去寫一些簡單的腳本,以進行一些系統維護的工作。shell可以像膠水一樣,將UNIX下的許單一的多功能組合在一起去完成一些復雜的工作。許多C語言需要上百行代碼才能完成的功能,在shell下只需要用幾行代碼。然而,shell的本質是調用命令,它并不是一個真正的編程語言。總之,shell不能全面的調動計算機的功能。

Guido非常希望有一種編程語言既可以像C語言那樣能夠全面地調用計算機提供的的功能接口,又可以像shelll那樣可以輕松的進行編程。

Python的誕生

image

1989年,Guido為了打發圣誕假期(看來,這也是個做IT的單身宅...),他開始寫Python語言的編譯器/解釋器。Python的名字來自Guido非常喜歡的電視劇 Monty Python's Flying Circus。他希望這個叫做Python的語言能夠是他一直想要的編程語言--介于C和shell之間,功能全面、易學易用、可擴展。

1991年,Python正式發布第一個版本。該版本用C語言實現了第一個Python編譯器(同時也是解釋器),并且它能夠調用C庫(.so文件),這為python編寫高效的C擴展模塊提供了先天性的條件。

Python的發展

促進Python發展的兩個主要原因

計算機性能提高

90年代初,個人計算機開始進入普通家庭。Intel發布了486處理器,windows發布了window 3.0開始的一系列視窗系統。計算機的性能大大提高,程序員開始關注計算機的易用性。

開源社區逐漸形成

1990年的個人電腦時代,許多程序員以及資深計算機用戶已經在頻繁使用Internet進行交流(包括email 和 newsgroup),這讓信息交流成本大大下降。當時Unix的商業化讓愛好開放、自由的IT從業人員感到崩潰,而GNU組織的成立促使一種新的軟件開發模式開始流行:open source。程序員利用業余時間進行軟件開發,并開放源代碼。1991年,Linus在comp.os.minix新聞組上發布了Linux內核源代碼,吸引了大批hacker的加入。Linux的出現之前,那些開源軟件只能跑在他們深惡痛絕的已經商業化的UNIX系統上。這是很滑稽,也是讓開源軟件開發者們感到非常的郁悶的。Linux的出現,讓他們重新找到了組織,Linux和GNU相互合作,最終構成了一個從滿活力的開源平臺。

Python各版本迭代

硬件性能不再是瓶頸,Python又容易使用,所以許多人開始轉向Python。另外,Guido后來宣布Python遵循GPL協議,Python從此走上了開源的道路,并且在開源社區的參與下開始快速發展。

  • 1989年,為了打發圣誕節假期,Guido開始寫Python語言的編譯器。他的愿望是:創造一種C和shell之間,功能全面,易學易用,可拓展的語言。
  • 1991年,第一個Python編譯器誕生。它是用C語言實現的,并能夠調用C語言的庫文件。從一出生,Python已經具有了:類,函數,異常處理,包含表和詞典在內的核心數據類型,以及模塊為基礎的拓展系統。
  • Granddaddy of Python web frameworks, Zope 1 was released in 1999
  • Python 1.0 - January 1994 增加了 lambda, map, filter and reduce.
  • Python 2.0 - October 16, 2000,加入了內存回收機制,構成了現在Python語言框架的基礎
  • Python 2.4 - November 30, 2004, 同年目前最流行的WEB框架Django 誕生
  • Python 2.5 - September 19, 2006
  • Python 2.6 - October 1, 2008
  • Python 2.7 - July 3, 2010
  • In November 2014, it was announced that Python 2.7 would be supported until 2020, and reaffirmed that there would be no 2.8 release as users were expected to move to Python 3.4+ as soon as possible
  • Python 3.0 - December 3, 2008
  • Python 3.1 - June 27, 2009
  • Python 3.2 - February 20, 2011
  • Python 3.3 - September 29, 2012
  • Python 3.4 - March 16, 2014
  • Python 3.5 - September 13, 2015

現狀

Python得到廣泛的認可和應用

自從2004年以后,Python的使用率呈線性增長。現在Python已經成為最受歡迎的程序設計語言之一。
2016年TIOBE編程語言排行榜圖:


由上圖可見,Python的使用率整體呈上升趨勢,說明Python逐漸得到了業內的認可,并且得到了越來越廣泛的應用。這得益于Python的簡單易學,但個人認為更重要的原因在于兩個方面:

  1. Python可擴展的模塊化架構
  2. Python走上開源之路,開源社區中提供了大量的實用的第三方庫

Python應用領域

Python現在被廣泛用于眾多領域:

  • 系統運維 通過Python提供API能方便的進行系統維護和管理,Python已成為Linux系統下的標志性語言之一;

  • 云計算 Python是目前云計算領域最火的語言,典型應用為OpenStack;

  • Web編程 出現了很多python的web開發框架,如django、tronado,flash等;Youtube、豆瓣、知乎、春雨醫生等公司所有業務幾乎都是用Python完成,另外python在google內部也被大量使用;

  • 科學計算、人工智能 NumPy擴展提供了大量標準數學庫的接口,其他的典型庫還有SciPy、Matplotlib、Enthgout librarys、pandas;

  • 文本處理 Python提供的re模塊支持正則表達式,還提供SGML和XML分析模塊;

  • 數據庫編程 程序員可以通過遵循Python DB-API(數據庫應用程序編程接口)規范的模塊與Microsoft SQL Server、Orace、DB2、MySQL、SQLite等數據庫進行通信;此外,Python自帶一個Gadfly模塊,提供了
    一個完整的SQL環境;

  • 網絡編程 Python提供了豐富的模塊支持socket編程,能方便快速地開發分布式應用程序;

  • 圖形處理 有PIL、Tkinter、PyQT等圖形庫支持,能方便進行圖形處理;

  • 其他 python可以用來做很多事其他的事情,如編寫爬蟲程序、多媒體應用、pymo引擎(AVG游戲引擎)

正在向Python 3.0過度

今天Python已經進入到3.0的時代。由于Python 3.0向后不兼容,所以從2.0到3.0的過渡并不容易。另一方面,Python的性能依然值得改進,Python的運算性能低于C++和Java(見Google的討論),因此Python依然是一個在發展中的語言。

二、Python是一門什么樣的語言?


編程語言從不同的角度可以進行不同的分類:

  • 低級語言和高級語言
  • 編譯型語言和解釋型語言
  • 靜態語言和動態語言
  • 強類型定義語言和弱類型定義語言

每個分類代表什么意思呢?我們一起來看下

低級語言和高級語言

低級語言是從計算機的角度出發的計算機語言,無法獨立于機器(特定的CPU體系結構)運行。最初的計算機程序都是用0和1的序列表示的,通過紙帶打孔進行輸入。這些0和1的序列稱為機器指令,即無需翻譯計算就可以直接執行的指令。后來為了方便記憶,就將用0、1序列表示的機器指令都用符號助記,這些與機器指令一一對應的主機符就成了匯編指令,從而誕生了匯編語言。機器指令和匯編指令都是面向機器的,統稱為低級語言。

高級語言是從人類的邏輯思維角度出發的計算機語言,抽象程度大大提高,可以獨立于機器運行。由于機器是無法理解人類的邏輯思維的,所有高級語言編寫的指令需要經過轉換成特定機器上的目標代碼才能執行,且一條高級語言的語句往往需要若干條機器指令來完成。高級語言獨立于機器的特性是靠編譯器為不同機器生成不同的目標代碼(或機器指令)來實現的。要將高級語言編譯到什么程度是跟編譯技術有關的,既可以編譯成直接可以執行的目標代碼,也可以編譯成一種中間表示,然后拿到不同的機器和系統上去執行,這種情況通常又需要相應的支撐環境,比如解釋器或虛擬機的支持。Java是一個很好的例子,Java源代碼會先被編譯成bytecode,再由不同平臺上的虛擬機執行。所以高級語言不依賴于機器是指在不同的機器或平臺上高級語言的程序源碼本身不用改動,而通過編譯器或解釋器得到相應的目標代碼區適用不同的機器。

編譯型語言與解釋型語言

兩者的區別

上面提到,高級語言是從人類的邏輯思維角度出發的計算機語言,抽象程度大大提高,所有高級語言編寫的指令需要被翻譯成特定機器上的目標代碼才能執行。這個翻譯的過程可以由編譯器來完成,也可以由解釋器來完成,只是他們轉換過程和時間不一樣:

  • 編譯型語言 是通過編譯器一次把所有代碼全部翻譯成機器語言,然后保存為可執行文件,下次可以直接運行,不用再次進行翻譯;其運行過程是這樣的:編譯-->執行-->執行-->執行...,翻譯和執行過程是分開的,典型語言是C語言、C++;
  • 解釋型語言 是在每執行到源程序的一條指令時,就要通過解釋器將這條指令翻譯成二進制代碼以供執行,每次執行都要進行這個翻譯過程;其運行過程是這樣的:解釋-->執行-->解釋-->執行...,翻譯和執行過程是一起完成的,典型語言是PHP,Javascript等;

這就好比你要閱讀一本英文書,而你又不懂英文,你就需要一位翻譯來幫助閱讀。你相當于計算機,而英文書相當于源代碼。你可以選擇讓這位翻譯將這本英文書全部翻譯成中文寫在紙上之后交給你,這就是編譯型;你也可以選擇讓這位翻譯幫你閱讀,但是你每次想看前面的內容就需要翻譯幫你重新翻譯一遍,這就是解釋型。

兩者的優缺點

編譯型語言和解釋型語言最大的不同體現在兩個方面:

  • 可移植性 解釋型語言的程序總是以源代碼的方式出現,因此只要有相應平臺上的解釋器,移植就幾乎不是問題;編譯型語言的程序雖然源代碼可以移植,但是需要針對不同的平臺進行分別編譯才能執行;
  • 執行速度 解釋型語言編寫的程序省卻了編譯步驟,因此修改調試非常方便,編輯完畢后即可立刻運行;但是解釋型程序要想被計算機執行,還是需要被翻譯成機器代碼的,只是這個翻譯的過程被放到了執行過程中,因此它的執行速度是比較慢的;而編譯型語言編寫的程序一個小小的改動都要重新編譯,如果工程很復雜的話,這個編譯過程是很漫長的;但是編譯型程序僅僅是在修改后才需要被重新編譯一次,之后執行時就可以直接執行了,因此它的執行速度是比較快的。

兩者的融合

編譯型語言與解釋型語言各有優點和缺點,并且這些優缺點是相互對立的,所以一批新型的語言都有把兩者折中起來的趨勢。例如Java語言在執行之前需要進行預編譯,但是這個預編譯不是直接生成目標代碼,而是介于機器碼和Java源代碼之間的中介代碼(Java 字節碼),然后由JVM(Java虛擬機,可視為解釋器,詳細解釋可以參考這里)解釋執行已達到提高執行速度的的目的;另外通過對不同平臺實現對應的JVM解釋器,使得Java字節碼可以在任何有JVM的平臺上被執行,這就實現了可移植型。
隨著設計技術與硬件的不斷發展,編譯型與解釋型這兩種方式的界限正在不斷的變得模糊。

靜態語言與動態語言

通常我們所說的靜態語言、動態語言是指靜態類型語言和動態類型語言:

  • 動態類型語言 在運行期間才去做數據類型檢查的語言,典型語言:PHP、Python、Perl等;
  • 靜態類型語言 在編譯期間進行數據類型檢查的語言,典型語言:C/C++、JAVA、Ocamal等;

這里糾正一個誤區:

很多人覺得C語言和JAVA等編程語言在定義變量時需要指定int、long這些數據類型,所以C和JAVA是靜態語言;而Python不用指定數據類型,直接寫變量名,所以Python是動態語言。這種理解是不夠準確的,譬如Ocaml是靜態類型的,但是也可以不用明確的將數據類型寫出來。靜態語言與動態語言最主要的區別在于:是在編譯時檢查變量數據類型還是再執行時檢查數據類型,而不在于是否在定義變量指定數據類型。

強類型定義語言和弱類型定義語言

  • 強類型定義語言 變量的數據類型不可以進行隱式轉換的編程語言;
  • 弱類型定義語言 變量的數據類型可以進行隱式轉換的編程語言;

這里糾正一個誤區:

很多人認為Python語言的一個變量可以多次賦值為不同數據類型的值,因此Python是弱類型的語言;C語言在定義變量時顯式的指定了數據類型,因此C語言是強類型的語言。實際上,強類型語言與弱類型語言的主要區別在于對數據類型進行檢查的嚴格程度,是否允許隱式類型轉換。如C語言的int可以變成double,所以C語言是弱類型的,而Python實際上是強類型定義語言。

結論

同上上面的介紹,我們可以得出一個結論就是:Python是一門動態的、強類型定義的、解釋性編程語言

各類型編程語言舉例:

  • 無類型: 匯編
  • 弱類型、靜態類型 : C/C++
  • 弱類型、動態類型: Perl/PHP
  • 強類型、靜態類型 :Java/C#
  • 強類型、動態類型 :Python, Scheme

image

關于各種編程語言類型的區別,大家可以看下知乎上的這篇帖子

三、Python優點與缺點


優點

  • 簡單易學、功能強大 python的定位時“優雅”、“明確”、“簡單”,但是功能卻很強大;

  • 豐富的庫、開發效率高 python有非常強大的第三方庫,基本上你想通過計算機實現的任何功能,python官方庫里都有相應的模塊進行支持;在基礎庫的基礎上進行開發,大大降低開發周期,提高了開發效率;

  • 高級語言、抽象程度高 用Python編寫程序的時候無需考慮過多底層細節,如如何管理程序使用的內存等;

  • 面向過程、面向對象 Python及支持面向過程編程,也支持面向對象編程;在面向過程的語言中,程序是由過程或僅僅是可重用代碼的函數構建起來的;而在面向對象的語言中,程序數據(屬性)和功能(函數/方法)組合而成的對象構建起來的;

  • 可移植性 由于它開源的本質、Python已經被移植在許多平臺上(經過改動使它能夠工作在不同平臺上);如果你小心的避免使用依賴于特定系統的特性,那么你的python程序無需修改就可以在幾乎所有的系統平臺上運行;

  • 可擴展性 如果需要一段關鍵代碼運行得更快或者希望某些算法不公開,可以將這部分程序用C/C++編寫,然后再Python中調用。

  • 可嵌入型 可以把Python嵌入C/C++程序中,從而實現向用戶提供腳本的功能;

缺點

  • 線程不能利用多CPU 這是Python被人詬病最多的一個缺點。Python的線程是操作系統的原生線程,在Linux上為pthread,在Windows上為Win thread,完全由操作系統調度線程執行。一個Python解釋器進程內有一條主線程,以及多條用戶程序的執行子線程。由于GIL(Global Interpreter Lock,全局解釋器鎖,它是計算機程序設計語言解釋器用于同步線程的工具,使得任何時刻僅有一個線程在執行)的存在,使得即使在多核CPU平臺上,還是會禁止多線程的并行執行。

  • 代碼不能加密 由于Python是一個解釋型語言,其源代碼都是以明文存在的。

  • 執行速度慢 這里是指與C和C++相比,Python確實要慢很多,這是由語言特性確定的;另外Python比Java也會慢一點,JVM比PVM的實現更底層一些,因此JVM在將字節碼翻譯為機器碼的速度也就更快一些。

  • 多行語句與命令行輸出問題 由于Python規定用縮進來表示代碼結構,而不支持分號分割,因此在大多數情況下不能將多條程序語句寫成一行;如果在shell下要使用多條python語句來完成一個功能時,必須將程序寫入.py文件中。

小結

其實編程語言只是一個實現我們想法的工具,任何一門語言都有其擅長和不擅長做的事情。就像我們拿一個人的劣勢和自己的優勢去比較一樣,拿一個語言的劣勢去跟另外一個語言的優勢去比較是沒有任何意義的。我們不應該把太多時間和精力放在這些毫無意義的口舌之爭上,那只能說明我們自己知識面太窄,水平還太low。

四、Python解釋器


解釋器的運行方式

解釋器的概念比較簡單,它可以將代碼進行翻譯并運行,不需要經過編譯,JVM中的解釋器就是這樣的。解釋器運行程序的方式有3種:

  1. 直接運行高級編程語言,如shell內置的解釋器;
  2. 先將高級語言轉換成一些效率更高的字節碼(Bytecode),然后再解釋執行這些字節碼,這種解釋器有兩種翻譯功能(源代碼-->字節碼,字節碼-->機器二進制語言),如:CPython解釋器;
  3. 以解釋器中包含的特殊編譯器對高級語言中間代碼(如字節碼)進行編譯,然后指示處理器運行編譯后的程序,如:PyPy解釋器 和 JVM中的解釋器(它們都包含一個JIT編譯器,JIT編譯器會將熱點代碼編譯結果緩存起來,從而達到加塊執行速度的目的);

Python的默認解釋器CPython就是屬于第二種,Python代碼在第一次被執行時會被CPython解釋器編譯成運行效率更高的字節碼,然后再逐條執行字節碼指令。如果可以的話,Python的字節碼會被保存到.pyc文件中,這樣下次執行該代碼時就可以直接解釋運行字節碼,而不用再去編譯源碼了。這與Java代碼的執行過程很相似,但是Java的源代碼編譯成字節碼的過程是由專門的編譯器(javac)來完成的,JVM中只是字節碼解釋器和一個JIT編譯器。可見這種機制正在模糊解釋器和編譯器之間的接線,或者說是模糊了解釋型語言和編譯型語言的界限。

Python解釋器分類

事實上,Python規定了一個Python語法規則,實現了Python語法的解釋程序就可以被稱為Python解釋器。由于Python語言從規范到解釋器都是開源的,所以任何有能力的人都可以編寫Python解釋器,而且確實存在多種Python解釋器:

  • CPython C語言實現的Python解釋器,這個Python默認使用的解釋器,也是使用最多的版本;從Python官方網站下載并安裝好Python之后,我們就直接獲得了一個官方笨的解釋器CPython;

  • Ipython 它是基于CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的;

  • Jython Java語言實現的運行在Java平臺上的Python解釋器,它可以直接調用Java的各種函數庫,也可以把Python代碼編譯成Java字節碼執行;

  • IronPython 面向.NET和ECMA CLI 的Python實現,它可以直接調用.net平臺的各種函數庫,也可以將Python程序編譯成.net程序執行;
  • PyPy Python語言寫的另一個Python解釋器,它的目標是執行速度。PyPy采用JIT技術,對Python代碼進行動態編譯(注意不是解釋),所以可以顯著提高Python代碼的執行速度。

參考文章:


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()