當前位置:
首頁 > 知識 > 亞馬遜、Oracle 程序員學習 Python 後的一點感悟

亞馬遜、Oracle 程序員學習 Python 後的一點感悟

推薦 | 編程派公眾號(ID:codingpy)

最近因為工作的關係開始學習 Python 了。以前從不曾正兒八經地學過,如果說工作學習經驗帶來改變的話,那麼編程語言的學習就是個很好的例子。如果在十年前,我要學習 Python 的話大概會買本系統介紹的 Python 教程,然後一頁一頁慢慢看,估計能夠啃完大半本,跳過一些自認為次要的特性。等到在項目中使用已經得是一兩個月之後了吧。

但是如今我顯然不太會做一樣的事情,*我現在會拿著我那些熟悉的編程語言來比較,不同的特性上面,Python 是怎樣的,是先進還是落後,適合解決什麼問題,在哪些領域可以大行其道,但在遇到哪些問題的時候事倍功半。*

想起以前接觸過的編程語言里,事實上有一半都不能算系統地學過,大致上只是零散地入了門,就開始在項目中使用了。自然,也不可能花很多時間琢磨透了再使用,靠的是時間和經歷一點點地積累。這個世界變化太快,已經沒有時間把每一步都踩紮實。這就是現實,有時候也未必是件壞事。

很多人覺得大學裡對編程語言的學習不值一提,因為象牙塔和工業界完全是不同的概念。但是我倒覺得,如果只考慮同等長度的時間範疇,大學裡的學習經歷,才是更有影響力的那一個。

工作快十年了,變化的東西太多,不變的也不少——看到一群程序員聚在一起進行語言的聖戰,在幾年前我可能會表達"不同的工具有不同的應用場景"這樣看起來中立而不帶無腦傾向的廢話。不過現在我可能什麼都不會說,但是饒有興緻地駐足觀看這樣的聖戰,有時候是罵戰。

首先,拿 Python 和以前學過的語言比較來看。我覺得和 Groovy 比較接近,特別是語言的動態性。我確信它的學習曲線也是比較簡單的。在 Linux 平台上作為腳本語言很容易使用,往往不需要準備什麼預裝什麼,這和其他腳本語言比起來,便有著不可替代的優勢。單純就語言層面上,Python 和 Bash 比起來它的代碼組織性更好,和 Perl 比起來則沒有那麼多啰嗦的語法,代碼更容易理解。僅由目前所掌握的這一點點知識來看,特別喜歡其中 yield 關鍵字的設計,讓一些本來需要反覆在不同方法上下文中切換的麵條代碼變得清晰和優雅,這也是我在其它語言中沒有見過的。

下面的內容是作為一個初學者的一點點記錄,覺得 Python 中有趣的幾點,以及項目中使用的一些感受。

首先,關於縮進。這大概是第一個縮進具備實際意義的編程語言了,縮進不僅僅是用於幫助理解和美觀需要了。對於痛恨滿天遍地括弧的程序員來說,似乎是一種解脫。

Tuple。Tuple 的最直接好處是不可變,它時常也被作為容器不同格式之間轉換和過渡的媒介,再一個,正因為有了 Tuple,讓函數"看起來"具備多個返回值也就變成了可能,以前在 Scala 中也使用過。印象中傳統語言裡面沒有這樣原生的東西,比如 Java 的 final 關鍵字除了不可變以外並不具備 Tuple 其它的特性。

可變參數:在 Java 中可變參數其實就是一個數組的語法糖,二者本質上沒有什麼區別。所以可以傳一個數組給變參方法,數組會被準確解析成變參;反過來轉換也一樣——在變參方法中,變參一拿到手就已經是一個數組了,Python 為了變參更舒服地調用而設計了展開符號——。則是關鍵字參數,和被解析成 [] 不同的是,被解析成 {},這個我在別的語言裡面似乎沒有見到類似的。如果不是說方法定義,而是說方法調用,那麼它似乎和 JavaScript ECMA 6 中的…類似,可以傳遞若干鍵值對(命名參數)。

尾遞歸優化(Tail Recursion Elimination, TRE)。這其實可以作為語言分類上的一個重要特性,Python 不支持尾遞歸優化,後續有機會再單寫一篇來詳細談談。

List Comprehension。我第一次接觸它是在 Haskell 里(曾經寫過 一點點東西 涉及到它)。它讓代碼的簡潔程度到達一個新的級別,比如下面這樣的兩個例子:

從 yield 到 generator。yield 這個關鍵字不僅僅可以讓函數多次返回,雖說這已經是一個頗為有趣的事情了,我在其他語言中我沒有見到過。它還可以讓函數變成 generator——其中一種簡單的定義方法是,如果函數定義中包含 yield,那麼它就成為了一個 generator,用於不斷生成結果並返回。

函數是順序執行,遇到 return 語句或者最後一行函數語句就返回。而變成 generator 的函數,在每次調用 next() 的時候執行,遇到 yield 語句返回,再次執行時從上次返回的 yield 語句處繼續執行。看這個例子:

例子中第一個 generator odditer 用來返回從 1 開始的所有奇數,而 mofthree 生成器用來過濾並返回其中 3 的倍數,最後一部分則是列印邏輯,列印 100 以內的結果。這個例子體現了 generator 的使用,也體現了它對無限序列的支持。

模塊的靈活性和自解釋能力。這也是我相當喜歡的一個特性。在 Python 中有這樣的規約,一個下劃線開頭表示私有變數,兩個下劃線開頭表示 Python 自身預定義的一些變數,這樣的規約即保留了違背規約訪問和使用這些變數的靈活性,也提供了很多預定義變數的可能。其中一個是模塊的init.py,類似於 Java 的 package.java,但是提供了更多的特性,用以模塊的自解釋,比如標準注釋、依賴、編碼、文檔注釋和立即執行的 main 方法等等。

而實際開發的時候,藉助 pip 和 virtualenv,可以說依賴和環境準備比多數語言都簡單多了。

最後是 decorator,這個其實最早我實在 Groovy 中見到的,現在很多語言都支持註解,但是原生來看似乎 Python 是使用它支持特性最豐富的,這裡不展開了。

在新的團隊中,我們的項目比較特別,大部分的服務端代碼都是用 Python 寫的。我可以看到 Python 在開發效率上和環境搭建上的優勢,從開發、測試、部署到調試,Python 都很易於使用,Linux 和命令行親和力高,不需要很多額外的工具。

總體來說,這一點在快速開發的場景下很吸引人。另一方面,Python 靈活和強調規約的特性,以及提供的元編程上豐富的支持,我以及好多次感到,在寫代碼的時候,可以用很簡潔的代碼,寫出看起來有點複雜的特性。現在我接觸的 Python 開源庫還不多,隨著學習的深入後續再慢慢研究和記錄,但是有了 pip 等等通用的統一的包管理工具,這一切看起來似乎要比傳統的 Java 和 C 要簡單很多。

不過,Python 代碼容易產生的問題不可謂不少。老實說,隨著代碼規模的增加,我更傾向於一個約束更強,類型系統嚴謹並且代碼代碼模板清楚統一的編程語言。Python 有些"太過靈活",無論是易讀性還是分層/模塊化,我都看到代碼中有很多需要改善的地方。

最常見的一個模式是,用 Python 寫一堆有關聯的類和方法,放在一個 py 文件裡面,在開始的時候很不錯,也避免了過度臃腫的類文件,但是很快,隨著代碼規模的增加,這個文件需要不斷被拆分和重構,但是重構這件事情卻不是那麼容易推動的。

程序員都知道,當我們說"未來再擴展"或者"以後再改進"的時候,這件事情多半是不會發生了——於是代碼過度耦合就變成了一個問題。以往使用 Java 寫代碼的時候,項目組彷彿有約定俗成的理念,無論是分層還是類文件設計,往往在開始的時候都顯得有些"過度",多層次的包、類設計,看起來似乎有些臃腫,但是隨著代碼規模的增加,好處就體現出來了,代碼的單一職責這一要求維護得明顯更好,在做某些修改的時候,需要評估的調查範圍就小,代碼修改也更清楚和易於評審者理解,修改者心裡也更有譜。

顯然這不能說孰好孰壞的問題,但是我對 Python 在中大規模項目(50 萬行 )上的使用是有疑慮的。當然也許隨著經驗的積累我會有不同的看法。

原文:https://www.raychase.net/4627

回復下方「關鍵詞」,獲取優質資源

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 編程派 的精彩文章:

81歲自學編程的開發者:阻礙你實現夢想的,從來就不是年齡
程序員的日常,竟是這樣的!

TAG:編程派 |