摘要:Python是一種跨平台的編程語言,能夠在所有主要的操作系統上,運行你編寫的任何Python程序。今天介紹幾款常見的工具:Python自帶的解釋器、文本編輯器(Geany、Sublime Text)、主流IDE(PyCharm、Jupyter Notebook),以及如何使用公有雲的計算資源在本地開發。
前言
Python is getting more attention than usual this year, becoming one of the most popular programming languages in the world.
-- by Krzyszt
對於技術類文章,我一般都會聯想到一些高大上的描述,或是一些人文故事。但是,對於Python這樣的全民化編程語言,我覺得上面這句來自Krzyszt的口語化描述,就足夠了。
Python是一種跨平台的編程語言,這就意味着它能夠在所有主要的操作系統上,運行你編寫的任何Python程序。今天文章里要給大家具體講講幾款常見的工具,包括了Python自帶的解釋器、文本編輯器(Geany、Sublime Text)、主流IDE(PyCharm、Jupyter Notebook),以及如何使用公有雲的計算資源在本地開發。
正文
Python自帶的解釋器
Python自帶了一個在終端窗口中運行的解釋器,你無需保存代碼,支持直接運行整個程序,如下所示:
Geany
Geany是一款簡單的文本編輯器,安裝很容易,支持直接運行幾乎所有的程序(不需要通過終端運行),支持使用顏色區分關鍵代碼,突出代碼語法。
我們可以在官網下載Geany軟件:https://geany.org/。
安裝完成后,首先在本地創建一個文件夾用於保存和運行代碼,例如python_work文件夾。
創建一個新文件,並且通過“SAVE AS”保存到pytthon_word文件夾。
如果你已經安裝了python,也就是說,如果能在系統中執行命令python,就無需配置Geany,如果不能執行順利執行python命令就需要對Geany進行配置。
涉及到編碼代碼和運行代碼的是“生成”按鈕,如下圖所示:
先來執行一個helloWolrld命令,如下圖所示:
進一步解釋“生成”下拉框所列的功能,我采用的是“阿姆斯特朗數”,即如果一個n位正整數等於其各位數字的n次方之和,則稱該數為阿姆斯特朗數。 例如1^3 + 5^3 + 3^3 = 153。
代碼如下:
# take input from the user num = int(input("Enter a number: ")) # initialize sum sum = 0 # find the sum of the cube of each digit temp = num while temp > 0: digit = temp % 10 sum += digit ** 3 temp //= 10 # display the result if num == sum: print(num,"is an Armstrong number") else: print(num,"is not an Armstrong number")
“Compile”:編譯代碼,類似於執行了python -m py_compile helloWorld.py,生成.pyc文件。pyc是一種二進制文件,是由py文件經過編譯后生成的文件,屬於byte code。py文件變成pyc文件后,加載的速度有所提高,而且pyc是一種跨平台的字節碼,是由python的虛擬機來執行的,這個是類似於JAVA或者.NET的虛擬機的概念。pyc的內容和python的版本相關,不同版本編譯后的pyc文件不完全相同,例如v2.5編譯的pyc文件在v2.4版本的 python上是無法執行的。
“Lint”:這個功能會對代碼做靜態檢測,例如制表符、空格、變量命名等等是否符合要求,本案例中部分行只縮進了3個空格,第18行的“num,”后面缺少空格,報錯如下所示:
代碼改動完畢后就顯示編譯正常,如下圖所示:
“生成目標文件”:運行”make current_file.o” 文件,好處是只會編譯當前指定的文件,而不是整個項目。
“Execute”:實際上調用Python的終端編譯器,如下圖所示:
Geany的操作界面和編譯器支持個性化配置,這里不逐一展開,你可以自己通過“編輯”-“首選項”嘗試。
Sublime Text
和Geany類似,Sublime Text是一款簡單的文本編輯器,能夠直接運行幾乎所有程序(無需通過終端),支持使用不同的顏色顯示關鍵代碼,突出代碼語法。
Sublime Text的優點:
- 跨平台: Sublime Text為跨平台編輯器(在Linux、OS X和Windows下均可使用)。作為一個程序員,切換系統是常有的事情,為了減少重復學習,使用一個跨平台的編輯器是很有必要的;
- 可擴展: Sublime Text是可擴展的(Extensible),並包含大量實用插件,我們可以通過安裝自己領域的插件來成倍提高工作效率;
- 互補: Sublime Text是命令行環境(CLI)和圖形界面環境(GUI)下的最佳選擇,同時使用兩者會大大提高工作效率。
從使用的角度看,Sublime Text真的是針對程序員的工具,舉一個例子,它的所有設置都是通過JSON配置文件完成的,支持你自己寫配置文件的方式,感覺很好。
如上圖所示,我在右邊的可編程欄設置了字體大小,只要保存這個文檔,Sublime Text已經打開的窗口會立即執行。
Sublime Text支持同時選擇多個區域,然后同時進行編輯。Ctrl + D選擇當前光標所在的詞並高亮該詞所有出現的位置,再次Ctrl + D選擇該詞出現的下一個位置,在多重選詞的過程中,使用Ctrl + K進行跳過,使用Ctrl + U進行回退,使用Esc退出多重編輯。這樣真是太棒了,寫代碼的人感覺自己的效率提升很多!
PyCharm
PyCharm是一個用於計算機編程的集成開發環境(IDE),主要用於Python語言開發,由捷克公司JetBrains開發,提供代碼分析、圖形化調試器,集成測試器、集成版本控制系統,並支持使用Django進行網頁開發。PyCharm是一個跨平台開發環境,擁有Microsoft Windows、macOS和Linux版本。社區版在Apache許可證下發布,另外還有專業版在專用許可證下發布,其擁有許多額外功能。
PyCharm非常強大,幾乎所有你自己可以想到的功能它都包含在內。我覺得判斷一個IDE的生命力,我們應該重點看是否支持代碼重構和利用周邊生態(例如公有雲計算資源),所以我這里重點介紹這兩個特性。
首先講代碼重構。重構指的是使用一系列重構手法,在不改變軟件可觀察行為的前提下,調整其結構。我們通常所講的代碼重構,最常見是的有幾類,例如重復代碼(一個以上的地點看到相同的程序結構)、過長的類(一般不超過500行)、過長參數列(太長的參數列難以理解,太多的參數會造成前后不一致、不容易使用,而且一旦你需要更多數據,就不得不修改它)、發散式變化(如果某個類經常因為不同的原因在不同的方向上發生變化,那么此時也許將這個對象分成兩個會更好,這么一來每個對象就可以只因為一種變化而需要修改)、冗余類,等等。
我們看一下具體的案例:
1、 常量和臨時變量
假設如以下代碼所示,你有一個字面數值, 帶有特別含義. 創建一個常量, 根據其意義為它命名, 並將上述字面數值替換為這個常量。
def potential_energy(mass, height): return mass * 9.81 * height
這里的9.81,改為GRAVITATIONAL_CONSTANT比較合適,
選Constant:
將代碼改為如下圖所示:
2、復雜表達式的簡單化,例如以下代碼:
if "MAC" in platform.upper() and "IE" in browser.upper() and was_initialized() and resize > 0: #do something
我們可以把"MAC" in platform.upper()改為變量,也就是說以變量名稱來解釋表達式用途。
代碼最終被重構如下圖所示:
3、 抽象出可以復用的方法,減少業務方法的代碼量。這里舉一個最大公約數的示例代碼
原始代碼如下:
現在我們將最大公約數提取到單獨的方法中,選中上面這張圖中的10-14行代碼,點擊‘重構’按鈕。
代碼重構為:
變量factor通過使用 Inline variable重構來擺脫變量。我們選中變量factor,然后按Ctrl+Alt+N。所有檢測到的factor變量都是內聯的。
使用使用Change Signature更改參數名稱。選中方法聲明行,然后按Ctrl+F6。在打開的dialog box中,分別將參數denom和num重命名為x和y,然后單擊圖標節點upLevel以更改參數的順序。
除了本地IDE工具功能以外,PyCharm能不能做得更好?我覺得就PyCharm自身來看,發展已經上了正規,我認為目前應該做的是生態的擴展,或者說聯合。與誰聯合?與公有雲。如果能夠做到在本地編碼、利用公有雲的計算資源進行調試,那相當於做到了雲邊協同。華為雲ModelArts提供了插件,支持讓本地的PyCharm與ModelArts結合在一起使用(詳細的過程請參考文檔:https://bbs.huaweicloud.com/blogs/160467)。
我們實際上只需要做三個步驟,即可支持本地的PyCharm與ModelArts平台結合使用:
1、 下載並安裝插件;
2、 ModelArts網站申請秘鑰;
3、 PyCharm填寫秘鑰鍵值對。
你把PyCharm想象成C/S設計模式的Client端,把ModelArts想象成Server端,就容易理解了。
我這里舉一個實際的使用案例—手寫字模型訓練案例。
登錄華為雲上傳OBS:
創建兩個文件夾,一個用於存放數據集,一個用於存放訓練生成的日志(需要傳回到PyCharm IDE並顯示):
填寫參數,可以參考ModelArts訓練模型時填寫的參數:
接着在PyCharm打開工程,點擊“Run Training Job”:
上面的日志輸出中,左下角是本地的輸出,右下角是ModelArts返回的雲端訓練日志。
訓練完成后,訓練模型保存在OBS中 /工程名/output/V0006/。
Jupyter Notebook
在AI研究探索場景中,Jupyter 作為一個特殊的存在迅速成長為AI探索類場景開發的首選,能夠在其各個階段滿足開發者訴求並覆蓋這些關鍵點,以及支持在瀏覽器中使用的特點。
Jupyter 起始於 IPython 項目,IPython 最初是專注於 Python 的項目,但隨着項目發展壯大,已經不僅僅局限於 Python 這一種編程語言了。按照Jupyter創始人的想法,最初的目標是做一個能直接支持Julia(Ju),Python(Py)以及R三種科學運算語言的交互式計算工具平台,所以將他命名為Ju-Py-te-R,發展到現在Jupyter已經成為一個幾乎支持所有語言,能夠把代碼、計算輸出、解釋文檔,多媒體資源整合在一起的多功能科學運算平台。
這里需要提到的另外一個概念就是“文學編程”,文學編程是一種由Donald Knuth提出的編程范式。這種范式提供了用自然語言來解釋程序邏輯的機會。簡單來說,文學編程的讀者不是機器,而是人。 從寫出讓機器讀懂的代碼,過渡到向人們解說如何讓機器實現我們的想法,其中除了代碼,更多的是敘述性的文字、圖表等內容。 文學編程中間穿插着宏片段和傳統的源代碼,從中可以生成可編譯的源代碼。
作為第一個貫穿整個科學計算研究的生命周期工具平台,可以將可以分解為,如果我們將科學計算研究全生命周期分解為,個人探索,協作與分享,生產化運行環境,發表與教學,Notebook都可以在這些階段中滿足科研工作的需求。
Jupyter有沒有缺點?有的。如果你追求的是產品化代碼開發,例如代碼格式、依賴管理、產品打包、單元測試等等功能在IDE中是沒有很好的支持,當前有一些插件可以做,但是相比重型IDE,功能還是比較弱。此外,Jupyter定義為研究類調試環境,一方面對於分布式的任務當前推薦都是通過單機多進程的方式進行模擬,真實到有多節點拓撲信息的部分在Jupyter中不容易實現,另外一方面,Jupyter的架構並不適合跑非常重量級的作業。對於真實軟件產品開發的訴求,還是需要在IDE中進行工程化代碼開發,並配搭測試邏輯,將任務部署在集群中進行運行。
我們具體看看Jupyter如何工作的?首先在公有雲上創建一個Notebook,點擊“打開”按鈕,如下圖所示:
選擇基於那個計算引擎(例如TensorFlow-1.8),如下圖所示:
輸出代碼片段,在第一段代碼中由於已經請求了用戶輸入,所以需要我們輸入一個數字,只要是正常的整形數字,不會報錯,如下圖所示:
后記
這篇文章的后記比較難寫,因為工具總是在不斷發展的,我們很難預料未來某一個工具的發展方向和趨勢,但是,永恆的定律是工具一定是為開發者服務的,一定是越來越簡單。
編輯器和IDE根本是面向兩種不同使用場景的工具:
- 編輯器面向無語義的純文本,不涉及領域邏輯,因此速度快體積小,適合編寫單獨的配置文件和動態語言腳本(Shell、Python和Ruby等);
- IDE面向有語義的代碼,會涉及到大量領域邏輯,因此速度偏慢體積龐大,適合編寫靜態語言項目(Java、C++和C#等)。
個人認為應當使用正確的工具去做有價值的事情,並把效率最大化,所以我會用IntelliJ IDEA編寫Java項目,用Vim編寫Shell,用Sublime Text編寫JavaScript/HTML/Python,用Visual Studio編寫C#。
工具再好用,代碼還是你自己寫的,因此本文的最后,我引用Python之禪(在Python交互式解釋器中輸 入import this就會顯示Tim Peters的The Zen of python):
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. 優美優於丑陋(以編寫優美的代碼為目標) Explicit is better than implicit. 明了優於隱晦(優美的代碼應當是簡潔明了的) Simple is better than complex. 簡單優於復雜(避免存在過多的復雜內部實現) Complex is better than complicated. 復雜優於凌亂(保持接口簡潔) Flat is better than nested. 扁平優於嵌套(避免多層嵌套) Sparse is better than dense. 間隔勝於緊湊(保持適當的間隔,不要奢望一行代碼解決問題) Readability counts. 可讀性很重要(保持並不斷提提升代碼的可閱讀感) Special cases aren't special enough to break the rules. 即使實用比純粹更優 Although practicality beats purity. 特例亦不可違背原則 Errors should never pass silently. 錯誤絕不能悄悄忽略 Unless explicitly silenced. 除非它明確需要如此 In the face of ambiguity, refuse the temptation to guess. 面對不確定性拒絕妄加猜測 There should be one-- and preferably only one --obvious way to do it. 任何問題應有一種且最好只有一種顯而易見的解決方法 Although that way may not be obvious at first unless you're Dutch. 盡管這方法一開始並非如此直觀除非你是荷蘭人(指的是Python之父荷蘭人Guido van Rossum) Now is better than never. 做優於不做 Although never is often better than *right* now. 然而不假思索還不如不做 If the implementation is hard to explain, it's a bad idea. 很難解釋的,必然是壞方法 If the implementation is easy to explain, it may be a good idea. 很好解釋的,可能是好方法 Namespaces are one honking great idea -- let's do more of those! 提倡使用命名空間
上面這些准備,並不單單適用於Python,編程語言體系都適用。