想要優質代碼?簡單九步幫你輕松實現
本文轉載自公眾號“讀芯術”(ID:AI_Discovery)
如今,擅長編寫代碼與精通英語一樣重要。想要變成優秀的程序員需要長期的磨煉,最好方法是加入一家有高編碼標準的公司。而筆者想要給你的,是如何通過簡單調整開發過程,以使代碼看起來更好。
本文匯集了筆者長期查看可補充學術論文的代碼,發布數據集或分析Kaggle競賽的解決方案總結而成的經驗。
本文的目標讀者是研究人員、數據科學家和初級軟件開發人員。每個步驟只需不到5分鐘,而且這些調整會迫使您做得更好。
使用版本控制來跟蹤代碼中更改的地方
版本化代碼看起來很明顯是必須做的事情,但事實并非如此。筆者的碩導是一個非常聰明的人,他開發了一種算法來執行Hubbard模型的Quantum Monte Carlo。該代碼被全世界許多研究人員使用,以推進理論的“凝聚態物理”。
當開始使用這種算法時,筆者驚訝地發現沒有集中式的存儲庫。代碼的交換是通過電子郵件進行的。一位科學家開發的漏洞修正和新功能并未交換給其他用戶。此外,我也看到同事如何使用不同的文件夾控制代碼版本。
在GitHub或其他服務上進行代碼版本控制和使用集中式存儲庫很有必要,許多研究人員正在這樣做。但是如果不使用計算機科學,那么大多數教授和研究生正處于使用文件夾進行版本控制和通過電子郵件發送代碼的階段。
問題:什么時候需要開始在項目中使用git?
回答:從代碼的第一行開始使用。
問題:何時需要在GitHub上創建存儲庫并將代碼推送到庫里?
回答:從代碼的第一行開始。如果認為由于法律或其他原因不能公開共享自己的代碼,那可以創建一個私人存儲庫。在其他所有情況下,請訪問公共存儲庫。
等到代碼看起來不錯再公開,這是一個錯誤。如果GitHub存儲庫中有不完美的代碼,我的許多同事都會感到非常不安全。他們擔心別人會認為自己是差勁的程序員。實際上,根本沒有人會去評判你。此外,現在編寫的每個代碼在六個月后看起來都會很糟糕。
私人存儲庫總比沒有存儲庫要好。公共存儲庫又比私有存儲庫更便利。
Kaggle競賽的參賽者在比賽結束后發布自己的pipeline是一個好習慣,對參賽者和社區都有幫助。
此外,還有一個名為Sourcegraph的工具,可以在所有公共Github存儲庫中的代碼中執行搜索。非常方便,能夠提高工作效率。
不要推送到主分支
在團隊中工作時,不要直接推送到主分支。創建一個單獨的分支,并在其中工作,創建一個拉取請求(PR),將拉取請求合并到主分支。這比直接的push to master 錯誤要復雜得多,原因是要合并拉取請求,更改須通過各種檢查。手動檢查是協作者進行的代碼審查。自動檢查包括語法、樣式、測試等。
當獨自工作時,沒有機會代碼審查,但是自動檢查的功能仍然可以使用。
在GitHub上調整設置非常有必要,即使有意愿,也不會出現push to master。如上所述,這可以防止犯錯誤并節省意志力。
圖源:unsplash
使用持續集成/持續交付(CI / CD)系統
完成創建分支和合并的過程是一項日常開銷,主要原因是允許對代碼更改執行檢查。設置持續集成系統后,創建的每個拉取請求需要進行檢查,并且僅在所有檢查通過后,才能合并拉取請求。
有許多提供CI /CD功能服務的軟件,如GitHub Actions、CircleCi、Travis、Buildkite等
推薦使用GitHubActions。完全免費,可在私有和公共存儲庫上使用,且易于設置。
這些聽起來非常復雜,但是實際上,只需要向存儲庫添加配置文件即可。
- 簡單示例:筆者的庫具有輔助功能。筆者檢查代碼樣式、格式并運行測試。
- 復雜示例:在Albumentations庫中,檢查語法和代碼樣式,運行測試,檢查自動文檔構建,并針對不同的python版本和操作系統(Linux,Windows,Mac OS)執行操作。
注意:需要在GitHub存儲庫中更改設置,這樣在所有檢查都在綠色區域中的情況下將無法合并請求。
Linters
這些工具不會更改代碼,而會對代碼進行檢查并查找可能存在的問題,這稱為linter。最常用的是flake8。
它可以尋找:
- Pep8錯誤和警告。
- 一致的命名公約。
- 功能的圈復雜度。
- 以及帶有一組插件的其他內容。
這是一個功能強大的工具,建議將其添加到CI /CD配置以及預提交鉤中。
Pre-commit hook
在上一步中,提到了提交之前在本地運行格式化程序的重要性。
假設使用black 和 isort,需要運行:
- black .isort
這很麻煩,更好的解決方案是使用這些命令(例如“code_formatter.sh”),創建一個bash腳本并運行腳本。
創建腳本這樣的方法非常流行,但問題是,除非強行使用,否則人們不會這樣做。
有一個更好的解決方案即預提交鉤(pre-commit hook)。這個想法類似于bash腳本,但是想要在每次提交之前運行的內容將在執行時運行:
- git commit -m“ <commitmessage>”
這看起來差別很小,但事實并非如此。有了預提交,行為就會被強制執行,如上所述,它的效果會更好。
圖源:unsplash
問題:PyCharm執行格式化很不錯。為什么需要一個預提交的鉤?
答案:因為可能會忘記使用PyCharm格式化代碼。此外,當有兩個人以上時,要確保他們的格式相同。預先提交鉤,所有人將擁有與存儲庫相同的配置。筆者建議同時使用這兩個方法,即預先提交鉤并使用PyCharm格式化代碼。
問題:如果跳過控制臺,直接從PyCharm執行提交會怎么樣的?
答案:可以將PyCharm配置為在每次提交時運行預提交鉤。
Mypy:靜態類型檢查器
從Python3開始,可以在代碼中的函數添加類型注釋。這不是必選項,但強烈推薦。其中一個原因在于,讀取帶有類型注釋的代碼非常容易。
當在代碼中看到:
- x:pd.DataFrame
這比僅僅輸入X能提供更多信息。當然,不應剛開始就將變量命名為“ x”。盡管如此,本文談論的是簡單且自動的方法來改進代碼,而好的命名要比簡單的輸入更難一些。
類型注釋是可選可不選的。沒有它們,代碼也能運行良好。有一個名為Mypy的工具可以進行檢查:
- 功能和輸入參數的類型注釋
- 變量類型與操作之間的一致性
這是一個非常有用的工具。所有大型的科技公司都使用它來檢查python代碼的每個拉取請求。
這個工具會強制編寫易于閱讀的代碼,重寫過于復雜、寫得不好的功能,并能識別錯誤。
Mypy檢查可以添加到CI /CD并預提交鉤。
代碼格式化程序
格式化同一段代碼的方法有很多。
- 函數之間要有多少空格?
- 代碼中的行要多長?
- 輸入的順序是什么?
- 應該使用哪種引號來定義字符串?
- 等等
有一些稱為代碼格式化程序的工具。如果要在代碼上運行代碼格式化程序,這些工具會修改代碼以符合格式化程序的要求。
通用的格式化程序類型:
- YAPF:非常靈活,可以進行配置以適合所需的樣式。
- Black:不夠靈活只可以配置行的長度。
選擇其中一個工具并將其添加到CI /CD配置。本人喜歡使用Black。這讓筆者所有的項目都看起來和Black的項目一樣。
代碼格式化程序減少了上下文切換,這讓讀取代碼變得更加容易。
還有更多特定的格式化程序,如isort。Isort只對輸入進行排序。
需要在兩個地方運行格式化程序:
- 在CI / CD中。以檢查模式運行:格式化程序將會告知要格式化的文件,但是代碼將保持不變。
- 提交更改之前需要在本地進行,并重新格式化代碼。
更多檢查以預提交鉤
可以使用許多不同的內容擴展預提交鉤。
- 刪除尾隨空格。
- 文件的末尾是新行。
- 文件格式要求txt。
- 檢查yaml文件,更正格式
- 等等
可以為代碼格式化創建自己的鉤子,并檢查自動產生的鉤子。
外部工具
像Deepsource.io和Deepcode.ai這樣的工具,可以用作對拉取請求自動代碼審查的附加檢查。
這是完全免費的公開存儲庫,很難找出不為公共代碼啟用它們的理由。
只要使用了其中的至少一種技巧,代碼會更加易于閱讀。但這只是第一步,還有其他標準的技巧,比如:單元測試、Hypothesis的單元測試、Python環境、創建安裝包、Dockerization、自動文件等等,這些會更難一點。
給自己不得不嘗試的理由,讓更好地工作成為自然而然的選擇。從第一步的改變開始吧!