python转go感觉难_读《我为什么从python转向go》的一些感受
一開始我以為是一篇2013年的老帖子,沒想到竟然是2015年。不懂Python不要亂噴啊。你直接說“我不懂Python,我也不愿意維護前任寫的糟糕代碼,我Go牛B,所以我要重構一遍!”我到覺得你智商正常點。。
我覺得go不錯,但是如果不是特定領域開發,沒有足夠多成熟穩定的庫仍然很麻煩的事情。
python雖然很強大,但我們在使用的時候也碰到了一些問題,主要由如下幾個方面:
動態語言
python是一門動態強類型語言。但是,仍然可能出現int + string這樣的運行時錯誤,因為對于一個變量,在寫代碼的時候,我們有時候很容易就忘記這個變量到底是啥類型的了(點評: 真的很少遇到, 每個函數的參數類型都有約定, 所以根本不會記不得)。
在python里面,可以允許同名函數的出現,后一個函數會覆蓋前一個函數,有一次我們系統一個很嚴重的錯誤就是因為這個導致的。(點評:遇到過,不過這也是不遵循約定導致的,命名不規范的緣故,在不同模塊采用相同的名稱是可以的,另外這個問題在靜態語言里也有啊,你鏈接到一個錯誤的庫上。 在運行時用后一個函數會覆蓋前一個函數,這也正是monkey patch存在的基礎。雖然我覺得如果在語言層面上對用戶可以對變量的類型進行顯式聲明的約束很有用)
上面說到的這些,靜態語言在編譯的時候就能幫我們檢測出來,而不需要等到運行時出問題才知道。雖然我們有很完善的測試用例,但總有case遺漏的情況。所以每次出現運行時錯誤,我心里都想著如果能在編譯的時候就發現該多好。(點評: 有了編譯時檢查運行時就不出錯了么? ?難道代碼寫完了就完了么? 差不多每次添加功能或者調試的時候,讀到感覺寫的不好或者寫的不清楚的,都要做些清理,畢竟人對于所使用的庫或者語言的理解是逐步深入的。?)
性能
其實這個一直是很多人吐槽python的地方,但python有它適合干的事情,硬是要用python進行一些高性能模塊的開發,那也有點難為它了。
python的GIL導致無法真正的多線程,大家可能會說我用多進程不就完了。但如果一些計算需要涉及到多進程交互,進程之間的通訊開銷也是不得不考慮的。
無狀態的分布式處理使用多進程很方便,譬如處理http請求,我們就是在nginx后面掛載了200多個django server來處理http的,但這么多個進程自然導致整體機器負載偏高。
但即使我們使用了多個django進程來處理http請求,對于一些超大量請求,python仍然處理不過來。所以我們使用openresty,將高頻次的http請求使用lua來實現。可這樣又導致使用兩種開發語言,而且一些邏輯還得寫兩份不同的代碼。(點評:不用django,沒有發言權,不過高頻的請求可以用Cython優化,現在的Cython已經比2013年的時候方便多了。。。)
同步網絡模型
django的網絡是同步阻塞的,也就是說,如果我們需要訪問外部的一個服務,在等待結果返回這段時間,django不能處理任何其他的邏輯(當然,多線程的除外)。如果訪問外部服務需要很長時間,那就意味著我們的整個服務幾乎在很長一段時間完全不可用。
為了解決這個問題,我們只能不斷的多開django進程,同時需要保證所有服務都能快速的處理響應,但想想這其實是一件很不靠譜的事情。
異步網絡模型
tornado的網絡模型是異步的,這意味著它不會出現django那樣因為外部服務不可用導致這個服務無法響應的問題。話說,比起django,我可是非常喜歡tornado的,小巧簡單,以前還寫過幾篇深入剖析tornado的文章了。雖然tornado是異步的,但是python的mysql庫都不支持異步,這也就意味著如果我們在tornado里面訪問數據庫,我們仍然可能面臨因為數據庫問題造成的整個服務不可用。(點評:歷史原因,幾乎所有Python的標準庫都是同步的,)
其實異步模型最大的問題在于代碼邏輯的割裂,因為是事件觸發的,所以我們都是通過callback進行相關處理,于是代碼里面就經常出現干一件事情,傳一個callback,然后callback里面又傳callback的情況,這樣的結果就是整個代碼邏輯非?;靵y。python沒有原生的協程支持,雖然可以通過gevent,greenlet這種的上patch方式來支持協程,但畢竟更改了python源碼。另外,python的yield也可以進行簡單的協程模擬,但畢竟不能跨堆棧,局限性很大,不知道3.x的版本有沒有改進。(點評: Python3.4引入asyncio,Python3.5引入的async和await,就算使用Twisted,也不會一堆callback啊。有沒有搞錯?不清楚跨堆棧)
開發運維部署
當我第一次使用python開發項目,我是沒成功安裝上項目需要的包的,光安裝成功mysql庫就弄了很久。后來,是一位同事將他整個python目錄打包給我用,我才能正常的將項目跑起來。話說,現在有了docker,是多么讓人幸福的一件事情。(點評: 沒有用過虛擬Python環境?virtualenv,python直接調用mysql connector,怎么會裝一堆庫?不明所以)
而部署python服務的時候,我們需要在服務器上面安裝一堆的包,光是這一點就讓人很麻煩,雖然可以通過puppet,salt這些自動化工具解決部署問題,但相比而言,靜態編譯語言只用扔一個二進制文件,可就方便太多了。( 點評:測試環境就是開發環境,你確定靜態編譯的不解決好依賴在別的機子上面就能跑?)
代碼失控
python非常靈活簡單,寫c幾十行代碼才能搞定的功能,python一行代碼沒準就能解決。但是太簡單,反而導致很多同學無法對代碼進行深層次的思考,對整個架構進行細致的考量。來了一個需求,啪啪啪,鍵盤敲完開速實現,結果就是代碼越來越混亂,最終導致了整個項目代碼失控。
雖然這也有我們自身的原因,譬如沒好的代碼review機制,沒有好的項目規范,但個人感覺,如果一個程序員沒經過良好的編碼訓練,用python很容易就寫出爛的代碼,因為太自由了。
當然,我這里并不是說用python無法進行大型項目的開發,豆瓣,dropbox都是很好的例子,只是在我們項目中,我們的python代碼失控了。(點評:好像沒有聽說用了那種語言代碼就不失控了,這根本就是拒絕小步重構,代碼模塊化差,模塊耦合度高等等一系列問題導致的,Python的實現代碼少,反而能夠有精力進行持續的快速改進。。)
上面提到的都是我們在實際項目中使用python遇到的問題,雖然最終都解決了,但是讓我愈發的覺得,隨著項目復雜度的增大,流量性能壓力的增大,python并不是一個很好的選擇。
(點評: Python存在問題嗎? 當然也有很多,比如
* 配套的異步庫太少且缺乏維護。
* 不能限制變量的類型(雖然有Python3.5的type hints,但是和注釋沒啥區別)
* 本身的計算性能比V8引擎的JavaScript要差很多(可以借助C)
有疑問加站長微信聯系(非本文作者)
總結
以上是生活随笔為你收集整理的python转go感觉难_读《我为什么从python转向go》的一些感受的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python做一个记事本_python如
- 下一篇: Logos讲解--逆向开发