新聞中心
本文轉(zhuǎn)載自微信公眾號「Python中文社區(qū)」,作者100gle 。轉(zhuǎn)載本文請聯(lián)系Python中文社區(qū)公眾號。

成都創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務領域包括:成都網(wǎng)站建設、成都網(wǎng)站設計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的文安網(wǎng)站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡建設合作伙伴!
從以前一個不會敲 Python 代碼的小白,到現(xiàn)在敲 Python 代碼賊溜的老鳥的過程中,除了通過大量的學習、實踐讓自己現(xiàn)在更容易寫出 Pythonic 的代碼外,大部分時間里還是多虧著有著許多好用的工具輔助我,去檢查我代碼中的問題,幫助我寫出更規(guī)范的代碼。
學習和實踐新知識可能對于大多數(shù)人來說都沒有統(tǒng)一的定式,但使用工具至少可以讓我們大家風格統(tǒng)一也更容易和他人協(xié)作共事。因此無論對于剛?cè)腴T的小白還是正在成長的新人來說,會使用能輔助你寫出更規(guī)范的代碼的工具也是十分有必要的。
black
隨著 PEP8 規(guī)范的提出,Python 社區(qū)也有了自己的一套關于 Python 代碼的規(guī)范指導。但我相信,大多數(shù)人其實并不會條分縷析地去瀏覽或記下規(guī)范里的大多數(shù)內(nèi)容,因為這些內(nèi)容往往都過于瑣碎,以至于在實際開發(fā)中我們很難做到去一邊寫代碼一邊去檢查我們是否合乎 PEP8 規(guī)范。所以最好的方法就是借助格式化工具幫我們完成這一機械的操作。
早期 Python 著名的格式化工具的有 autopep8 和 Google 的 yapf,但在實際過程中或多或少需要一些配置。
如果你使用過 Go 語言,那可能會對 Go 自帶的 gofmt 贊嘆不已。因為它既不會要求你進行多余的配置,還能在每次保存代碼時強制幫你進行格式化,所以無論和你協(xié)作的同事們代碼風格和個人習慣如何,它都能將其轉(zhuǎn)換成符合工程的、規(guī)范的樣式。
而 black 就是類似于 gofmt 這樣號稱 「不妥協(xié)」(uncompromising)的 Python 格式化工具,它讓我們將更多的時間和精力放在編寫代碼上,而無需過度關注于格式化的配置細節(jié)。因此當我們在團隊協(xié)作中只要是使用了 black 工具之后,大部分情況下代碼看起來都是十分統(tǒng)一的。
比如說下面這一段代碼(來源于官方示例):
- def very_important_function(template: str, *variables, file: os.PathLike, engine: str, header: bool = True, debug: bool = False):
- """Applies `variables` to the `template` and writes to `file`."""
- with open(file, 'w') as f:
- ...
由于 very_important_function 已經(jīng)加上了類型注解,因此在現(xiàn)有的部分參數(shù)所占寬度的基礎上又擴展了一些,所以如果我們顯示器的寬度不夠時,就需要橫向拖動才能查看參數(shù)信息;而最好的辦法就是采取豎向的方式進行排列,便于我們能自上而下的一覽無遺。所以使用 black 之后上述代碼將會是這樣:
- def very_important_function(
- template: str,
- *variables,
- file: os.PathLike,
- engine: str,
- header: bool = True,
- debug: bool = False,
- ):
- """Applies `variables` to the `template` and writes to `file`."""
- with open(file, "w") as f:
- ...
可以看出,經(jīng)過格式化后的函數(shù)其參數(shù)層次分明地對齊,可讀性大大的增強了;并且如果需要對函數(shù)中的參數(shù)進行注釋或增加,直接新增或減少一行即可,絲毫不會額外調(diào)整其他參數(shù)的位置。
盡管說 black 還是一個實驗項目,但它早已頻繁被使用在一些主流的 Python 開源項目中,比如 Pandas、SQLAlchemy、Pytest 等,所以就算在實際開發(fā)中我們一樣可以沒有顧慮地使用它。
使用 black 的方式很簡單,通過 pip install black 安裝到你的 Python 環(huán)境中,然后在代碼中運行:
- black <項目文件夾 / 源碼文件夾 / .py 文件等>
black 命令行也提供了一些參數(shù)項(但不會太多),我們大部分時候即使我們使用默認的也是足夠了的,具體我們可以參考 black 的官方文檔。
isort
isort 是一個名為 PyCQA(Python Code Quality Authority)組織所維護的代碼質(zhì)量工具中的其中一個開源項目,它同樣是用來對代碼進行格式化。但不同于 black 的是,它主要用來格式化我們 import 的庫或模塊。
Python 社區(qū)的生態(tài)一直都是十分豐富,所以在開發(fā)項目的過程中我們往往會使用到多個庫或同一個庫中的多個模塊,但在缺乏規(guī)范的情況下,被導入的部分可能會凌亂、無組織地分散在我們的代碼中,所以當我們復現(xiàn)代碼時很可能就會因為忘記導入某些模塊而報錯。
就像官方給出的示例代碼一樣:
- from my_lib import Object
- import os
- from my_lib import Object3
- from my_lib import Object2
- import sys
- from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14
- import sys
- from __future__ import absolute_import
- from third_party import lib3
- print("Hey")
- print("yo")
上述的代碼存在了多種 import 風格,比如同一模塊下分別導入的部分各占一行、同一模塊下導入的部分只站一行等;并且還存在重復導入的情況。因此要么我們就干脆每個導入的部分只占一行,要么就是來自同一模塊下的導入部分都連接在一起。默認情況下 isort 會是后者:
- from __future__ import absolute_import
- import os
- import sys
- from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,
- lib9, lib10, lib11, lib12, lib13, lib14, lib15)
- from my_lib import Object, Object2, Object3
- print("Hey")
- print("yo")
使用了 isort 之后它會將我們每個 .py 文件下中 import 部分的代碼進行規(guī)整,同時它會按照內(nèi)置庫(及字母順序)、第三方庫以及本地自有模塊的次序?qū)ξ覀兯鶎氲牟糠诌M行排列。這樣我們的代碼不僅看起來清爽了許多,同時也能準確定位到我們已經(jīng)導入的部分有哪些。
isort 不會像 black 那樣「執(zhí)拗」,而是也給你盡可能地預留了一些可供自定義的配置項,以便能滿足不同風格或團隊規(guī)范的需要。但對它的使用和 black 一樣簡單,只需要將其安裝到我們的環(huán)境中后,直接調(diào)用即可:
- isort <項目文件夾 / 源碼文件夾 / .py 文件等>
靜態(tài)檢查工具
由于像 Python、JavaScript 這些動態(tài)類型的解釋型語言,不具備 Java、Go 這樣靜態(tài)類型的編譯型語言在編譯期時的檢查機制,因此當一個項目中的代碼量過多時,就會造成「動態(tài)一時爽,重構(gòu)火葬場」的局面。
盡管 Python 社區(qū)推行了 PEP484 提案并讓 Python 擁有了類型注解的能力,但不正確的使用依舊是很難達到靜態(tài)語言編譯檢查的那種效果。所以,一些靜態(tài)類型檢查工具也就應運而生,以便能及時發(fā)現(xiàn)我們代碼中的問題
目前關于 Python 的靜態(tài)檢查工具有許多,知名的有那么幾個:
- pylint:PyQCA 團隊維護,提供了高度的可配置項(這當然也是缺點),如果你有在 VS Code 編寫過 Python 代碼,那么有可能就會碰到讓你安裝 pylint 的情況;
- flake8:仍是由 PyQCA 團隊維護,它在功能上和 pylint 存在重疊的地方,但它也集成了 PEP8、McCabe 以及第三方插件等多個部分,功能上比 pylint 相對豐富一些;
- mypy:由 Python 的締造者 Guido van Rossum(Python 使用者們親切將其稱為龜叔)在 Dropbox 工作時所創(chuàng)建,可以說沒有人比他更了解 Python 了,也可以算作是相對權(quán)威靜態(tài)檢查工具了;
- pyright 由微軟開源的、基于 TypeScript 和 JavaScript 編寫,高度集成于 VS Code,對于經(jīng)常使用 VS Code 來寫代碼的人來說或許是個比較好的選擇;
- pytype 由谷歌開源并維護,但相對于其他工具來說檢查會較為寬松一些。
以上都是使用人數(shù)多的、并且質(zhì)量都較為上乘靜態(tài)檢查工具,可以根據(jù)自己或團隊的實際需要來選擇;不過 flake8 和 mypy 通常都算是一個正規(guī)項目中的標配了,這里我就只以 flake8 為例。
和前面兩個的工具一樣,先通過 pip install flake8 命令安裝之后再使用:
- flake8 <項目文件夾 / 源碼文件夾 / .py 文件等>
大部分情況下,flake8 會根據(jù)默認的一些規(guī)范對代碼進行檢查,默認是依照 pyflake 的錯誤(或違規(guī))碼表來進行檢查,你可以在 flake8 官方 《Error/Violation Codes》 一章中瀏覽到完整的碼表;當然我們也可以通過特定的命令行參數(shù)來指定檢查的事項或忽略掉的事項:
- flake8 --select E121 example.py
這里就只會選擇檢查 E121 這項來自于 pycodestyle 碼表中的一項,如果代碼導入的模塊或包沒有縮進或懸掛,那 flake8 就會在檢查代碼之后拋出信息:
- example.py:5:9: E121 continuation line under-indented for hanging indent
這里就對應著 example.py 文件里的第 5 行到第 9 行代碼,我們直接就可以根據(jù) flake8 的結(jié)果精準修改檢驗不通過的部分即可。
工具鏈整合
上述說的幾個工具,大部分情況都能通過 IDE、腳本、Git Hook 等途徑得到有效整合。通常情況下我都會在每次提交代碼到倉庫前預先分別使用 isort、black 以及靜態(tài)檢查的 flake8。
由于 black 的情況會比較特殊,像 isort 這樣的格式化工具處理過后的代碼都會 black 再次格式化,因此 black 也給出了兼容其他工具的配置項共同選項,盡最大程度的和其他工具共存。根據(jù) black 官方的建議,通常我們可以放在某些配置文件中,比如 pyproject.toml、setup.cfg 等,內(nèi)容如下:
- multi_line_output = 3
- include_trailing_comma = True
- force_grid_wrap = 0
- use_parentheses = True
- ensure_newline_before_comments = True
- line_length = 88
同理,flake8 也是如此:
- max-line-length = 88
- extend-ignore = E203, W503
因此我們可以將以上內(nèi)容都寫在一個配置文件中,這里我選的是 setup.cfg 文件中:
- [isort]
- multi_line_output = 3
- include_trailing_comma = True
- force_grid_wrap = 0
- use_parentheses = True
- ensure_newline_before_comments = True
- line_length = 88
- [flake8]
- max-line-length = 88
- extend-ignore = E203, W503
這樣就能使得 black、isort 和 flake8 能夠更好地協(xié)同工作;同時我們可以將其放在一個腳本文件中,方便每次運行調(diào)用,大致類似于:
- # code_fmt.sh
- WORKDIR=$PWD
- isort $WORKDIR \
- && black $WORKDIR --skip-string-normalization \
- && flake8 $WORKDIR
當然我們也可以將其集成在我們的 IDE 中,比如在 VS Code 中,當我們安裝好上述工具后,可以在設置項中關于 Python 的配置項里找到關于上述工具的配置欄目。這里我就以 black 為例:
isort、flake8 的設置也是類似。
然后再次在設置中找到關于編輯器的設置,并勾選 Format on Save 的選項,這樣在我們每次保存代碼文件時,就會自動幫我們格式化:
標題名稱:Python工具鏈讓你寫的代碼更規(guī)范
網(wǎng)頁URL:http://www.5511xx.com/article/dphhpgj.html


咨詢
建站咨詢
