網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
手把手教你用Python中的Linting提高代碼質(zhì)量_python
作者:Python數(shù)據(jù)開(kāi)發(fā) ? 更新時(shí)間: 2023-03-15 編程語(yǔ)言前言
Python 是一種不斷發(fā)展的語(yǔ)言。隨著它的演化和擴(kuò)展,可用工具和開(kāi)發(fā)策略的數(shù)量也在增加。近來(lái)流行的一個(gè)過(guò)程是linting —— 檢查代碼的潛在問(wèn)題。通過(guò)linting,我們代碼中的錯(cuò)誤會(huì)被標(biāo)記出來(lái),這樣我們就可以糾正可能導(dǎo)致出現(xiàn)問(wèn)題的編程方法。
Linting(提示)是在編寫(xiě)源代碼時(shí)和編譯前進(jìn)行的。換句話說(shuō),Linting是一種構(gòu)建前的檢查,也叫 “靜態(tài)代碼分析”。定期檢查我們的代碼,以確保整個(gè)代碼和代碼庫(kù)的一致性。這最大限度地減少了小錯(cuò)誤在代碼運(yùn)行后變成復(fù)雜問(wèn)題的機(jī)會(huì)。
許多開(kāi)發(fā)人員不使用Linting,因?yàn)樗麄儧](méi)有看到它的附加價(jià)值,因?yàn)長(zhǎng)inting不會(huì)防止錯(cuò)誤。但這種觀點(diǎn)低估了Linting在提高代碼質(zhì)量方面的價(jià)值。
在這篇實(shí)踐文章中,我們將探討在Python中使用Pylint——最流行的提示工具之一——進(jìn)行快速的提示檢查是多么快速和簡(jiǎn)單。我們還將看到,對(duì)代碼進(jìn)行提示是如何幫助我們遵守PEP8代碼風(fēng)格指南的。
前提條件
在開(kāi)始之前,確保滿足以下條件:
在你的機(jī)器上安裝了Python和pip
對(duì)命令行界面(CLI)有基本的了解
對(duì)Python概念的理解,如函數(shù)和類(lèi)。
另外,應(yīng)該注意,雖然這里顯示的命令與Linux和基于macOS的系統(tǒng)兼容,但在Windows下工作時(shí),你應(yīng)該小心。
Linting Python 代碼
在我們深入研究如何在Python中使用linter之前,讓我們通過(guò)創(chuàng)建一個(gè)目錄和虛擬環(huán)境來(lái)進(jìn)行設(shè)置。
建立環(huán)境
首先,為這個(gè)項(xiàng)目創(chuàng)建一個(gè)目錄。在本教程中,我們把它叫做 pylint-demo
。
$ mkdir pylint-demo $ cd pylint-demo
接下來(lái),創(chuàng)建一個(gè)虛擬環(huán)境。這將隔離我們的項(xiàng)目依賴性,并防止與其他項(xiàng)目發(fā)生沖突。
$ pip install pipenv $ pipenv shell
命令行應(yīng)該是這樣的。(pylint-demo)$
。這表明虛擬環(huán)境已經(jīng)激活。
在虛擬環(huán)境激活的情況下,使用下面的命令安裝linter。
$ pipenv install pylint
現(xiàn)在我們可以用pylint命令運(yùn)行l(wèi)inter。為了確保Pylint已經(jīng)成功安裝,運(yùn)行以下命令。
$ pylint –help
開(kāi)始使用 Linting
讓我們寫(xiě)一個(gè)基本的Python程序,并在其上使用Pylint,看看它是如何工作的。創(chuàng)建一個(gè) main.py
文件并復(fù)制以下代碼。
def is_number_even(num): return "Even" if num % 2 == 0 else "Odd" num = 5 print(f"The number {num} is {is_number_even(num)}")
在上面的代碼中,我們已經(jīng)添加了一個(gè)函數(shù)來(lái)檢查數(shù)字是偶數(shù)還是奇數(shù)。為了使用Pylint來(lái)檢查這段代碼中的錯(cuò)誤,我們使用以下命令:
$ pylint <<file_name>> $ pylint main.py
Pylint的輸出情況如下:
************* Module main
main.py:12:0: C0304: Final newline missing (missing-final-newline)
main.py:1:0: C0114: Missing module docstring (missing-module-docstring)
main.py:8:0: C0116: Missing function or method docstring (missing-function-docstring)
main.py:8:19: W0621: Redefining name 'num' from outer scope (line 11) (redefined-outer-name)
main.py:11:0: C0103: Constant name "num" doesn't conform to UPPER_CASE naming style (invalid-name)------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)
我們可以在代碼中看到幾個(gè)不言而喻的問(wèn)題,每個(gè)問(wèn)題都用一個(gè)字符標(biāo)識(shí),如 C0304
。Pylint將字母代碼應(yīng)用于所有錯(cuò)誤,以區(qū)分問(wèn)題的嚴(yán)重程度和性質(zhì)。有五個(gè)不同類(lèi)別的錯(cuò)誤。
- C: 慣例(針對(duì)任何違反代碼慣例的行為)
- R:重構(gòu)(針對(duì)任何與代碼氣味和重構(gòu)有關(guān)的問(wèn)題)
- W:警告(針對(duì)任何不屬于錯(cuò)誤的編程級(jí)問(wèn)題)
- E: 錯(cuò)誤 (對(duì)于任何編程級(jí)別的問(wèn)題,是一個(gè)錯(cuò)誤)
- F: Fatal (對(duì)于任何停止Pylint執(zhí)行的嚴(yán)重問(wèn)題)
Pylint還根據(jù)存在的錯(cuò)誤數(shù)量給我們的代碼打分,滿分為10分。
在我們的例子中,除了一個(gè)錯(cuò)誤代碼外,所有的錯(cuò)誤代碼都是約定俗成的錯(cuò)誤——單個(gè)錯(cuò)誤是一個(gè)警告。為了解決這些問(wèn)題,讓我們?cè)谖覀兊拇a中做一些修改,然后再次運(yùn)行Pylint,看看我們的代碼得到什么分?jǐn)?shù)。
""" File contains various function to under Pylint """ def is_number_even(num): """Function to check if number is even or odd""" return "Even" if num % 2 == 0 else "Odd" NUM = 5 print(f"The number {NUM} is {is_number_even(NUM)}")
通過(guò)這段代碼,我們添加了一個(gè)模塊和函數(shù)docstring,在結(jié)尾處添加了一個(gè)新行,并重新命名了上述代碼中的變量。當(dāng)我們重新運(yùn)行Pylint時(shí),我們得到了10/10的分?jǐn)?shù),沒(méi)有任何問(wèn)題。
在單個(gè)文件上運(yùn)行Pylint
現(xiàn)在我們對(duì)Pylint的工作方式更加熟悉了,讓我們看看另一個(gè)例子,輸入以下代碼:
""" File contains various function to under Pylint """ class animal: def __init__(self, name): self.name = name obj1 = animal("Horse", 21) print(obj1.name)
在這個(gè)片段中,我們有一個(gè)簡(jiǎn)單的類(lèi),名為 animal
,該類(lèi)的一個(gè)對(duì)象名為 obj1
。現(xiàn)在讓我們?cè)谶@段代碼上使用Pylint:
************* Module main
main.py:4:0: W0311: Bad indentation. Found 2 spaces, expected 4 (bad-indentation)
main.py:5:0: W0311: Bad indentation. Found 4 spaces, expected 8 (bad-indentation)
main.py:3:0: C0115: Missing class docstring (missing-class-docstring)
main.py:3:0: C0103: Class name "animal" doesn't conform to PascalCase naming style (invalid-name)
main.py:3:0: R0903: Too few public methods (0/2) (too-few-public-methods)
main.py:7:7: E1121: Too many positional arguments for constructor call (too-many-function-args)
請(qǐng)注意,雖然這次我們沒(méi)有代碼質(zhì)量問(wèn)題,但它們已經(jīng)被更多實(shí)質(zhì)性的錯(cuò)誤所取代。有了這些問(wèn)題的標(biāo)記,讓我們?cè)囍孟旅娴拇a來(lái)修復(fù)它們:
""" File contains various function to under Pylint """ class Animal: "Animal Class" def __init__(self, name): self.name = name obj1 = Animal("John") print(obj1.name)
然后,重新運(yùn)行Pylint。在將類(lèi)的名稱從 animal
改為 Animal
,為類(lèi)添加一個(gè)文檔字符串,刪除函數(shù)調(diào)用中不需要的參數(shù),并添加適當(dāng)?shù)目s進(jìn),我們幾乎消除了代碼中的錯(cuò)誤。不過(guò)還剩下一個(gè):
************* Module main
main.py:3:0: R0903: Too few public methods (0/2) (too-few-public-methods)
讓我們看看如何解決這個(gè)剩余的錯(cuò)誤。Pylint說(shuō)我們沒(méi)有兩個(gè)或多個(gè)公共方法,但我們的代碼很有可能沒(méi)有兩個(gè)或多個(gè)公共方法。那么,我們?cè)撊绾谓鉀Q這個(gè)問(wèn)題呢?
在這樣的情況下,我們可以使用Python注釋來(lái)抑制這些問(wèn)題。抑制它們的語(yǔ)法如下。
# pylint: disable=<<issue_name>>
下面是完整代碼:
""" File contains various function to under Pylint """ # pylint: disable=too-few-public-methods class Animal: "Animal Class" def __init__(self, name): self.name = name obj1 = Animal("John") print(obj1.name)
當(dāng)我們現(xiàn)在檢查Pylint的輸出時(shí),我們會(huì)看到這個(gè)問(wèn)題已經(jīng)消失了。
在一個(gè)目錄上運(yùn)行Pylint
我們已經(jīng)看到了如何在單個(gè)文件上運(yùn)行Pylint,但是當(dāng)我們?cè)谝粋€(gè)項(xiàng)目上工作時(shí),我們不會(huì)有單個(gè)文件可以檢查。
要在整個(gè)目錄上使用Pylint,請(qǐng)運(yùn)行以下命令。
$ pylint << name_of_directory >>
為了了解對(duì)一個(gè)目錄的提示是如何工作的,讓我們?cè)賱?chuàng)建兩個(gè)文件并添加一些代碼。
$ mkdir src; cd src $ touch helpers.py config.py __init__.py
將 main.py
文件移到 src
目錄,并將以下代碼粘貼到相應(yīng)的文件中。
<<main.py>> """ File contains various function to under Pylint """ from helpers import connect_db from config import DB_USER, DB_PASS is_connected = connect_db(DB_USER, DB_PASS) if is_connected: print("Connected to DB") else: print("Failed to connect to DB") <<helpers.py>> def connect_db(user, password): """Dummy function to connect to DB""" if user is None or password is None: return False return True <<config.py>> DB_USER = "root" DB_PASS = "toor"
我們?cè)?src
目錄下有三個(gè)文件:main.py
、 helpers.py
和 config.py
。在 main.py
中,我們有一個(gè)假函數(shù)來(lái)打印我們是否連接到了DB。helpers.py
包含一個(gè)假的幫助函數(shù)來(lái)連接到DB, config.py
文件包含DB的用戶名和密碼。
現(xiàn)在,讓我們?cè)诟夸浵率褂靡韵旅钤谡麄€(gè)目錄上運(yùn)行Pylint。
$ pylint src
命令的輸出將如下:
************* Module src.config
src/config.py:2:0: C0304: Final newline missing (missing-final-newline)
src/config.py:1:0: C0114: Missing module docstring (missing-module-docstring)
************* Module src.main
src/main.py:11:0: C0304: Final newline missing (missing-final-newline)
src/main.py:3:0: E0401: Unable to import 'helpers' (import-error)
src/main.py:4:0: E0401: Unable to import 'config' (import-error)
************* Module src.helpers
src/helpers.py:6:0: C0304: Final newline missing (missing-final-newline)
src/helpers.py:1:0: C0114: Missing module docstring (missing-module-docstring)
我們可以看到,Pylint向我們顯示了不同文件的輸出,用 ***
和模塊名稱分開(kāi)。為了解決這些問(wèn)題,我們需要做以下修改。
- 在每個(gè)文件的末尾添加一個(gè)新行。
- 為每個(gè)文件和函數(shù)添加一個(gè)文檔串。
- 將
import
語(yǔ)句從helpersimportconnect_db
修改為.helpersimportconnect_db
。
一旦我們解決了這些問(wèn)題,我們會(huì)看到另一個(gè)問(wèn)題——我們需要將 is_connected
變量大寫(xiě)。我們可以改變變量名稱,或者抑制警告來(lái)處理這個(gè)錯(cuò)誤。
抑制警告
在對(duì)Python代碼進(jìn)行檢查時(shí),你很有可能需要定制或抑制多個(gè)警告。每次都添加注釋是沒(méi)有意義的。你可以創(chuàng)建一個(gè) .rc
文件來(lái)定制Pylint的行為,并直接從 .rc
文件中抑制整個(gè)項(xiàng)目的警告,而不是一個(gè)一個(gè)地處理警告抑制實(shí)例。
你可以用下面的命令創(chuàng)建一個(gè):
$ pylint -- generate - rcfile > pylint . rc
用Linting更好、更安全地編寫(xiě)代碼
在Python中,在代碼編寫(xiě)過(guò)程中對(duì)源代碼進(jìn)行檢查,并在我們運(yùn)行代碼之前,沿途標(biāo)記出錯(cuò)誤。你也可以將Pylint嵌入到編輯器中,實(shí)時(shí)查看提示信息。
雖然提示并不能自動(dòng)修復(fù)錯(cuò)誤,但持續(xù)使用它有助于確保我們的代碼質(zhì)量保持高水準(zhǔn)。因此,雖然有些開(kāi)發(fā)者認(rèn)為linting是浪費(fèi)時(shí)間,但它在小問(wèn)題滾雪球般發(fā)展成大問(wèn)題之前就能極其有效地捕捉到。
在這篇文章中,我們已經(jīng)探討了如何通過(guò)linting和實(shí)施Pylint的建議來(lái)改善我們的示例代碼。此外,這個(gè)過(guò)程本質(zhì)上有助于我們遵守PEP8的風(fēng)格指南。現(xiàn)在,你可以在你的項(xiàng)目中實(shí)施linting,你可以探索許多可用的linting工具,并確定哪種工具最能補(bǔ)充,并增強(qiáng)你的Python開(kāi)發(fā)方法。
總結(jié)
原文鏈接:https://blog.csdn.net/m0_59596937/article/details/128710303
相關(guān)推薦
- 2022-07-13 Pycharm使用技巧_Pycharm配置autopep8
- 2022-12-26 Python?gRPC流式通信協(xié)議詳細(xì)講解_python
- 2022-12-05 C++?Boost?MultiArray簡(jiǎn)化使用多維數(shù)組庫(kù)_C 語(yǔ)言
- 2023-04-06 Docker報(bào)錯(cuò)Operation?not?permitted問(wèn)題的解決方法_docker
- 2022-02-19 數(shù)據(jù)結(jié)構(gòu)C語(yǔ)言鏈表的實(shí)現(xiàn)介紹_C 語(yǔ)言
- 2023-07-25 mybatis-plus在實(shí)際開(kāi)發(fā)中的應(yīng)用
- 2022-08-20 oracle?delete誤刪除表數(shù)據(jù)后如何恢復(fù)_oracle
- 2022-11-14 CSS樣式中選擇器+盒子模型+定位+浮動(dòng)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支