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