<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python 工具鏈讓你寫的代碼更規(guī)范

          共 6942字,需瀏覽 14分鐘

           ·

          2021-03-28 15:14

          從以前一個不會敲 Python 代碼的小白,到現(xiàn)在敲 Python 代碼賊溜的老鳥的過程中,除了通過大量的學(xué)習(xí)、實踐讓自己現(xiàn)在更容易寫出 Pythonic 的代碼外,大部分時間里還是多虧著有著許多好用的工具輔助我,去檢查我代碼中的問題,幫助我寫出更規(guī)范的代碼。
          學(xué)習(xí)和實踐新知識可能對于大多數(shù)人來說都沒有統(tǒng)一的定式,但使用工具至少可以讓我們大家風(fēng)格統(tǒng)一也更容易和他人協(xié)作共事。因此無論對于剛?cè)腴T的小白還是正在成長的新人來說,會使用能輔助你寫出更規(guī)范的代碼的工具也是十分有必要的。

          black

          隨著 PEP8 規(guī)范的提出,Python 社區(qū)也有了自己的一套關(guān)于 Python 代碼的規(guī)范指導(dǎo)。但我相信,大多數(shù)人其實并不會條分縷析地去瀏覽或記下規(guī)范里的大多數(shù)內(nèi)容,因為這些內(nèi)容往往都過于瑣碎,以至于在實際開發(fā)中我們很難做到去一邊寫代碼一邊去檢查我們是否合乎 PEP8 規(guī)范。所以最好的方法就是借助格式化工具幫我們完成這一機械的操作。
          早期 Python 著名的格式化工具的有 autopep8 和 Google 的 yapf,但在實際過程中或多或少需要一些配置。
          如果你使用過 Go 語言,那可能會對 Go 自帶的 gofmt 贊嘆不已。因為它既不會要求你進(jìn)行多余的配置,還能在每次保存代碼時強制幫你進(jìn)行格式化,所以無論和你協(xié)作的同事們代碼風(fēng)格和個人習(xí)慣如何,它都能將其轉(zhuǎn)換成符合工程的、規(guī)范的樣式。
          black 就是類似于 gofmt 這樣號稱 「不妥協(xié)」(uncompromising)的 Python 格式化工具,它讓我們將更多的時間和精力放在編寫代碼上,而無需過度關(guān)注于格式化的配置細(xì)節(jié)。因此當(dāng)我們在團(tuán)隊協(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ù)所占寬度的基礎(chǔ)上又?jǐn)U展了一些,所以如果我們顯示器的寬度不夠時,就需要橫向拖動才能查看參數(shù)信息;而最好的辦法就是采取豎向的方式進(jìn)行排列,便于我們能自上而下的一覽無遺。所以使用 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ù)進(jìn)行注釋或增加,直接新增或減少一行即可,絲毫不會額外調(diào)整其他參數(shù)的位置。
          盡管說 black 還是一個實驗項目,但它早已頻繁被使用在一些主流的 Python 開源項目中,比如 Pandas、SQLAlchemy、Pytest 等,所以就算在實際開發(fā)中我們一樣可以沒有顧慮地使用它。
          使用 black 的方式很簡單,通過 pip install black 安裝到你的 Python 環(huán)境中,然后在代碼中運行:
          black <項目文件夾 / 源碼文件夾 / .py 文件等>
          black 命令行也提供了一些參數(shù)項(但不會太多),我們大部分時候即使我們使用默認(rèn)的也是足夠了的,具體我們可以參考 black 的官方文檔。

          isort

          isort 是一個名為 PyCQA(Python Code Quality Authority)組織所維護(hù)的代碼質(zhì)量工具中的其中一個開源項目,它同樣是用來對代碼進(jìn)行格式化。但不同于 black 的是,它主要用來格式化我們 import 的庫或模塊。
          Python 社區(qū)的生態(tài)一直都是十分豐富,所以在開發(fā)項目的過程中我們往往會使用到多個庫或同一個庫中的多個模塊,但在缺乏規(guī)范的情況下,被導(dǎo)入的部分可能會凌亂、無組織地分散在我們的代碼中,所以當(dāng)我們復(fù)現(xiàn)代碼時很可能就會因為忘記導(dǎo)入某些模塊而報錯。
          就像官方給出的示例代碼一樣:
          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 風(fēng)格,比如同一模塊下分別導(dǎo)入的部分各占一行、同一模塊下導(dǎo)入的部分只站一行等;并且還存在重復(fù)導(dǎo)入的情況。因此要么我們就干脆每個導(dǎo)入的部分只占一行,要么就是來自同一模塊下的導(dǎo)入部分都連接在一起。默認(rèn)情況下 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 部分的代碼進(jìn)行規(guī)整,同時它會按照內(nèi)置庫(及字母順序)、第三方庫以及本地自有模塊的次序?qū)ξ覀兯鶎?dǎo)入的部分進(jìn)行排列。這樣我們的代碼不僅看起來清爽了許多,同時也能準(zhǔn)確定位到我們已經(jīng)導(dǎo)入的部分有哪些。
          isort 不會像 black 那樣「執(zhí)拗」,而是也給你盡可能地預(yù)留了一些可供自定義的配置項,以便能滿足不同風(fēng)格或團(tuán)隊規(guī)范的需要。但對它的使用和 black 一樣簡單,只需要將其安裝到我們的環(huán)境中后,直接調(diào)用即可:
          isort <項目文件夾 / 源碼文件夾 / .py 文件等>

          靜態(tài)檢查工具

          由于像 Python、JavaScript 這些動態(tài)類型的解釋型語言,不具備 Java、Go 這樣靜態(tài)類型的編譯型語言在編譯期時的檢查機制,因此當(dāng)一個項目中的代碼量過多時,就會造成「動態(tài)一時爽,重構(gòu)火葬場」的局面。
          盡管 Python 社區(qū)推行了 PEP484 提案并讓 Python 擁有了類型注解的能力,但不正確的使用依舊是很難達(dá)到靜態(tài)語言編譯檢查的那種效果。所以,一些靜態(tài)類型檢查工具也就應(yīng)運而生,以便能及時發(fā)現(xiàn)我們代碼中的問題
          目前關(guān)于 Python 的靜態(tài)檢查工具有許多,知名的有那么幾個:
          • pylint:PyQCA 團(tuán)隊維護(hù),提供了高度的可配置項(這當(dāng)然也是缺點),如果你有在 VS Code 編寫過 Python 代碼,那么有可能就會碰到讓你安裝 pylint 的情況;
          • flake8:仍是由 PyQCA 團(tuán)隊維護(hù),它在功能上和 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 由谷歌開源并維護(hù),但相對于其他工具來說檢查會較為寬松一些。
          以上都是使用人數(shù)多的、并且質(zhì)量都較為上乘靜態(tài)檢查工具,可以根據(jù)自己或團(tuán)隊的實際需要來選擇;不過 flake8 和 mypy 通常都算是一個正規(guī)項目中的標(biāo)配了,這里我就只以 flake8 為例。
          和前面兩個的工具一樣,先通過 pip install flake8 命令安裝之后再使用:
          flake8 <項目文件夾 / 源碼文件夾 / .py 文件等>
          大部分情況下,flake8 會根據(jù)默認(rèn)的一些規(guī)范對代碼進(jìn)行檢查,默認(rèn)是依照 pyflake 的錯誤(或違規(guī))碼表來進(jìn)行檢查,你可以在 flake8 官方 《Error/Violation Codes》 一章中瀏覽到完整的碼表;當(dāng)然我們也可以通過特定的命令行參數(shù)來指定檢查的事項或忽略掉的事項:
          flake8 --select E121 example.py
          這里就只會選擇檢查 E121 這項來自于 pycodestyle 碼表中的一項,如果代碼導(dǎo)入的模塊或包沒有縮進(jìn)或懸掛,那 flake8 就會在檢查代碼之后拋出信息:
          example.py:5:9: E121 continuation line under-indented for hanging indent
          這里就對應(yīng)著 example.py 文件里的第 5 行到第 9 行代碼,我們直接就可以根據(jù) flake8 的結(jié)果精準(zhǔn)修改檢驗不通過的部分即可。

          工具鏈整合

          上述說的幾個工具,大部分情況都能通過 IDE、腳本、Git Hook 等途徑得到有效整合。通常情況下我都會在每次提交代碼到倉庫前預(yù)先分別使用 isort、black 以及靜態(tài)檢查的 flake8。
          由于 black 的情況會比較特殊,像 isort 這樣的格式化工具處理過后的代碼都會 black 再次格式化,因此 black 也給出了兼容其他工具的配置項共同選項,盡最大程度的和其他工具共存。根據(jù) black 官方的建議,通常我們可以放在某些配置文件中,比如 pyproject.tomlsetup.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
          當(dāng)然我們也可以將其集成在我們的 IDE 中,比如在 VS Code 中,當(dāng)我們安裝好上述工具后,可以在設(shè)置項中關(guān)于 Python 的配置項里找到關(guān)于上述工具的配置欄目。這里我就以 black 為例:

          isort、flake8 的設(shè)置也是類似。
          然后再次在設(shè)置中找到關(guān)于編輯器的設(shè)置,并勾選 Format on Save 的選項,這樣在我們每次保存代碼文件時,就會自動幫我們格式化:

          作者:100gle,練習(xí)時長不到兩年的非正經(jīng)文科生一枚,喜歡敲代碼、寫寫文章、搗鼓搗鼓各種新事物;現(xiàn)從事有關(guān)大數(shù)據(jù)分析與挖掘的相關(guān)工作。


          贊 賞 作 者



          更多閱讀



          2020 年最佳流行 Python 庫 Top 10


          2020 Python中文社區(qū)熱門文章 Top 10


          5分鐘掌握 Python 對象的引用

          特別推薦




          點擊下方閱讀原文加入社區(qū)會員

          瀏覽 97
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人最新网址 | 俺来俺去www色官网 | 日韩无码黄色片 | 国产精品一二三级 | 国产精品久久久一区二区三区四区 |