天天看點

如何為使用Python語言而辯論

如何為使用Python語言而辯論

這篇文章的用意是幫助表明Python仍然對大多數軟體項目是切實可行的。我不擔心把Python推銷給反對其他動态語言(如Ruby)的人,因為我認為這些争論與個人喜好有關。這篇文章是講給那些推銷靜态類型語言的人。具體上,這篇文章是針對Go的,但也可以是其他任何靜态類型語言。

“為什麼Go?”,你可能會問。因為Go實際上在擷取Python的使用者。當2003到2005年間Python的增長曲線是個曲棍球棒時,Python還不是被推下山巅的王者,而是個弱者。傳統上,Python從Java之類的語言陣營中獲得使用者,并且留住了他們(我不想談C++使用者,因為通常他們有嚴格的性能需求,需要一個系統語言,或者是性能成瘾者,并且需要好好恢複)。但是Go的情況不太一樣。如今Python是使用最多的語言之一,而不再是弱者了。一旦在靜态類型語言社群中出現一門語言,它的生産效率/性能的取舍相當好,那便足以說服一些Python的程式員選擇Go而不再是Python了。

如今的Go

首先我應該說,Go是目前我第二喜歡的語言。如果今天我要啟動一個項目,但不能說服人們使用Python,那我會提議使用Go。不要誤解我在本文中說Go是門不好的語言。這篇文章的要點是說服其他人,Python是生産率/性能取舍遊戲中Go之外切實可行的替代方案,而不是表達Go是門不好的語言。認為這篇文章是反Go的,那就是你的個人想法,而且不應該這樣認為。

我應該說,我偶爾在工作中使用Go,并有點想關注這門語言的社群。既然我不能僅憑想象就成為Go專家,但這番話并不是僅從文檔或者部落格中提取出來的。但是由于我是Python開發團隊的一份子,無論我如何試圖表現得公平,固有的偏見某種程度上還是有的。

那麼,帶着這些警告,我們來看下Go提供給開發者什麼。

生産率

我看待Go的方式是,使用你最喜歡的程式設計語言,移除那些難于加速生産率的特性,就是Go。靜态類型的影響被降到最小,因為通常隻有在API邊界時你才會面對它。結構類型同樣使事情變得簡單(把它認為是鴨子類型)。文法并不笨拙(雖然它使用了花括号)。不要認為Go是C/C++去掉不安全的特性,加上生産率更高的東西,不然你會很失望(比如,“為什麼我不能使用make()内置函數,也不能像map類型一樣對傳回值進行計數”,這種看待Go的方式是錯誤的;這就是為什麼C++開發者沒有轉到Go的原因)。快速編譯也使開發周期更像一個動态語言,而不是一個需要編譯的語言。而且事實上有些人喜歡沒有異常機制帶來的冗長,因為這促使你處理每種異常情形而不是(意外地)忽略它們(這是貫穿Go初始系統語言設計的執行個體)。還有,這門語言本身相當短小易記,并有嚴格的前向相容性要求(forward-compatibility

requirements)(你不可能更快地獲得泛型),大體上使用Go來編碼是件很愉快的事情。

由于是靜态類型,Go可以很容易地獲得工具支援(它對之前以此為設計目标的語言也有幫助)。Go確定核心工具跟随Go本身提供,也是明智之舉。go

fmt強制執行Go風格的規則,并允許通過使用者自定義的規則來重構代碼(“采用制表符縮進”不再是問題,因為這意味着你可以随心所欲地設定編輯器來代表制表符,然後go

fmt将其轉換為普通制表符以适用VCS)。go fix會更新代碼以跟最新釋出的版本保持一緻。go get擷取依賴并安裝。

Go最後一個生産率功能是它靜态編譯所有東西,使部署更簡單。如果你使用容器來開發和部署,這也不算什麼。隻有當你釋出單個檔案的指令行工具,而不是一組依賴和你自己的代碼時,這才算得上事。

性能

就性能來說,Go做的很好。很難指出任何基準能準确的證明Go總是最快的選擇,甚至計算機語言基準遊戲中一些基準證明CPython 3是最快的。但是通常情況下可以認為對于你的任何工作來說Go已經足夠快了。

Go真正出色的地方是并發性(concurrency) 。要注意并發代碼并不是通常誤解的并行(parallelized)代碼;

并發代碼仍然可以是單線程的,僅僅在任務切換方面更加簡單/出色。Go通過使用goroutine使連續并發的代碼執行起來絕對的簡單。如果你不想使用共享記憶體的方式(雖然也同樣支援),該語言提供的通信管道允許以非常簡潔的消息傳遞方式進行并發程式設計。将所有特征整合進此語言中成為盡可能使用該語言開發并發代碼的又一原因。換句話說,Go程式運作很快,該語言盡力使你在合理的方式上獲得該效果。

如今的Python

如果順利的話我已經讓你相信Go是一種優秀的程式設計語言,除非因為其他原因,一些人不會認為我在整篇文章對Go的描述很糟糕。現在我們讨論一下Python的生産率/性能是怎麼樣的。

首先也是最重要的,Python非常容易學習。這也是為什麼在目前高評價的美國大學中将Python作為首選的教學語言

。這相當于該語言擁有成熟穩定的新程式員的來源以及更容易教育訓練其他程式員。

我想,要說服别人隻用幾行Python代碼就會完成很多工作這并不難(Go/Python 3比較

顯示Python每次都比Go使用更少的代碼完成相同的工作)。是以我會堅持認為使用Python會更高産,即使和Go相比,這不會有人反對。

通常大家反對Python的地方是在工具支援方面。但是如果你注意到我指出的Go相關的支援工具,fmt, fix, 和 get,

Python社群也有對等的工具。對遵循PEP 8的風格格式化(style formating),

可以在送出檢查時使用pep8,或者如果想要更多go fmt風格的自動重寫可以使用autopep8。對用于重構的go fix或go

fmt,你可以說2to3也可以完成同樣的功能。對于go get,

Python有pip。我們有venv/virtualenv或cx_Freeze這樣的代碼當機工具(跟其他一樣,位于容器之上?on top of

containerization like anything

else),而不是靜态編譯的二進制包。甚至有貫穿項目的代碼分析工具如pylint。說Python因為缺少工具支援而不能用于大型項目,這種觀點對我來說是很膚淺的。

如果說有哪方面Python完全做的好,那就一定是它豐富的第三方擴充庫和相應的工具可供使用,就像在PyPI上面看到的那樣(我相信肯定有人忍不住要争論說,“并不是所有的第三方庫都能夠在Python3上面運作啊”,事實确實如此,然而,這些第三方擴充庫對Python3的支援已經相當好了,而且還在繼續改善中,是以我不會太在意這個争論,另外,你可以同時使用Python2/3兩個版本進行編碼,不需要關心針對哪個版本)。看一下godoc.org,上面顯示Go也并不缺少社群支援,Pytho之是以能夠擁有更多可用的第三方庫僅僅是因為它的年齡,這個狀态也會繼續持續。

因為Python已經存在很久,且變得如此龐大, 簡單地去說 “Python是足夠快的” 不能說明整個的情況,

那是因為有各種各樣的實作加速的方式。但是在深入到VM級别的選項之後,意味着Python的stdlib提供了獲得加速的選項。舉例來說,

concurrent.futures 是尴尬地執行并行代碼的方式,這種方式是極其簡單的。而在Python

3.3中,新的asyncio編寫了異步代碼。它沒有像Go那樣被內建進語言,在Python中的并發程式設計是可行的,且在方式上也未必是那麼痛苦的。

但是最好的辦法是,你可以在選擇的VM裡改變Python代碼的性能。

本文作者:magicoding

來源:51CTO