95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

編程語言 Python 程序員 Linux python薔薇 python薔薇 2017-11-02

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

根據你的說法,編程人員可能在編碼時可能會犯的最常見的Python編程錯誤是什麼?那麼我們中有些人習慣於做這些基本的編碼錯誤。在這裡,我們將指導您如何發現這些並提高您的代碼質量。但是,瞭解這些問題的背景是公平的。 小編推薦一個群,有很多熱愛python聚集在了一起,並整理了大量的學習資料上傳到了群文件當中,喜歡python的朋友可以加入python群:526929231歡迎大家交流討論各種技術,一起快速成長


令人驚訝的是,研究顯示,大多數這些錯誤恰好是過去編程經驗中常見的誤解的副作用。例如,在學習編程時,沒有意識到你犯了一些錯誤。有時候,你不知道你犯錯誤並在程序中留下空白。

它也反映出你很容易。而學習計劃是艱鉅的任務,每個人都會接受誰做的。

但最重要的是你可以從錯誤中學習。你可以把他們當成增長的機會。所以,如果你做了一個,你不應該感到羞恥。事實上,每個錯誤都是一個重要的教訓,要了解你攜帶,直到你成為一名專家。一個好的程序員永遠不會跑掉,而是接受他們作為發展道路上的里程碑。

儘管如此,在本文中,我們列出了一些Python編程錯誤,並嘗試為其中的每個提供一個解決方案。

首先,您可以通過以下清單來幫助您避免基本的Python編程錯誤。它列出了程序/應用程序的一些關鍵要素,並提出了幾點進行改進。

  • 標識符:確保所有標識符都有意義。避免單個字母和名稱,如temp / flag。

  • 模塊化:使用函數和類拆分邏輯。不要重新開發一個庫程序。

  • 格式化:在Python中縮小代碼時要小心。使用空格而不是製表符,並按照一致的縮進模式。

  • 評論對 Docstring: Python支持Docstring。比使用傳統評論更方便。確保您的所有功能都有一個Docstring。

  • 代碼分析:在代碼上運行PyLint這樣的工具。它有助於捕獲低懸掛的水果,如未定義的變量,基本的打字錯誤,未使用的代碼等。

  • 單元測試:不要錯過單元測試你的代碼。使用測試模塊,如<unittest>或<unittest.mock>,並提供開發測試代碼。

  • 代碼分析:不要猜到未知數,而是找到它們。添加模塊,如<timeit>或<cprofile>來查找代碼中的隱藏問題。

常見的Python編程錯誤避免。

1.忽略Python範圍規則(LEGB)。

如果您不知道Python範圍規則,那麼您犯錯誤的可能性很大。這是因為與其他編程語言相比,Python對範圍變量使用了一些不同的方法。例如,它允許訪問在循環內聲明的變量或來自外部的if語句。對於來自C / C ++背景的人來說,這可能有點混亂。

以下是Python範圍界定規則(又稱為LEGB)的簡要概述。

  • L -代表Local。它包含(標識符/變量)在函數中指定的名稱(使用def或lambda),而不是使用global關鍵字聲明。

  • E -代表封閉功能當地人。它包含來自任何/所有封閉函數的本地範圍的名稱(例如,使用def或lambda)。

  • G -指全球實體。它包括在模塊文件的頂層操作的名稱或使用global關鍵字定義的名稱。

  • B -指內置。它將預先分配的名稱作為內置的名稱,如打印,輸入,打開等。

LEGB規則指定命名空間的以下順序,用於搜索名稱。

本地 - >封閉 - >全局 - >內置。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

Python LEGB規則概覽。

因此,如果特定的<name-> object>映射在本地命名空間中不可用,那麼將在附帶的範圍內查找。如果它不成功,那麼Python將移動到全局命名空間,並繼續搜索內置的。如果在任何命名空間中找不到名稱,則會引發NameError。

要詳細瞭解LEGB規則,請考慮以下示例。它展示了Python範圍規則的實際用法和影響。在這個例子中,我們使用了四個函數來演示Python中範圍規則的應用。

LEGB示例。

1.功能:<access_local()> -它使用名為“token”的本地變量(它也存在於全局命名空間中),並用某些值初始化。然後,它查詢本地和全局命名空間,以確認它們在兩者中的存在。最後,打印“token”變量以確保它不引用全局變量。

2.功能:<access_enclosed()> -它有一個for循環並在循環內初始化令牌變量。然後,它檢查全局命名空間,它也包含令牌變量。接下來,它打印令牌變量的值,它是在附帶的for-loop中設置的值。它證明在封閉範圍內定義的變量的優先級高於全局變量。功能:<access_global()>

3.函數:<access_global()> -在這個函數中,首先,我們確認在全局命名空間中存在令牌變量。然後,印刷它的價值與我們在開始時所設定的一樣,即在全球一級。

4.功能:<id()> - 在這裡,我們創建了我們自己定義的內置的“id()”函數。而根據LEGB規則,內置優先級最低。所以每當我們調用“id()”函數,Python將引用全局命名空間中可用的一個。

5- NameError - 如上所述,使用未定義的變量會拋出NameError。你可以看到發生在下面的代碼的最後一個聲明。在這一行中,我們嘗試打印導致錯誤的“token1”。

示例代碼

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

以上是Python代碼的輸出。要解釋以下結果,請參考示例中給出的說明。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

誤認認同為平等。

Python程序員提交的另一個常見錯誤是在比較整數時誤認為<等於>等於。由於Python用於緩存整數,所以他們可能不知道這個錯誤。

要理解這個概念,我們來考慮以下兩個例子。

實施例-1。

在下面的第一個例子中,我們使用了兩個名為<sum>和<add>的變量。並且每個都存儲兩個整數的和。然後,我們將兩個變量與等式(==)運算符進行比較。它將返回true,因為兩個變量都保持相同的值。接下來,我們使用identity(“is”)運算符來測試它們,但也返回true。原因是Python為它們分配了相同的地址。您可以從最後打印的id值確認。

但程序員沒有意識到兩個不同的操作(“==”和“is”)產生相同的結果。並且在不知不覺中犯了這個錯誤。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

但是,在下一個例子中

例2。

在這個例子中,我們考慮使用長整數。這裡的一點是,Python只在-5到256之間緩存整數。而大數字佔據了它們的單獨的一個盒子才能睡覺。

因此,在將大整數與身份(“is”)運算符進行匹配時,不會產生與上一個示例中所看到的相同的結果。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

3.在您的代碼中不合理地使用反模式。

一般來說,反模式是一種常見問題的設計方法,暫時解決問題,但可能存在副作用。

在這裡,我們正在討論程序員在編碼時可能會使用的一些Python反模式。

3.1 使用Java風格的Getter和Setter函數。

通常將Java稱為最佳實踐來定義訪問類的成員的get / set函數。並且您可以看到這種模式被應用於使用Java Hibernate Framework的應用程序中。

相反,在Python中使用這些功能會導致額外的代碼沒有真正的好處。

反模式示例:以Java風格實現Python類。

最好的Java最終對於Python是不一樣的。所以如果你來自Java背景,你必須謹慎地思考Python的工作方式。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

方法-1:你應該如何在Python中執行

在Python中,可以直接訪問或操作類成員。通常,Python中使用受保護的或私有的是稀缺的。默認情況下,Python中的成員也是公開的,直到您使用<_>或<__>為其添加前綴。這樣,您可以模仿它們的行為就像受保護(帶_)或私有(帶__)。Python以_ _>或_ __>前綴混淆變量的名稱,以將它們從課外的代碼中疏離出來。

我們刪除了get / set函數後,您應該會看到下面的代碼。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

方法-2:使用內置的<Property>可以像Get / Set函數一樣工作。

在某些情況下,當隱藏成員時,您可以使用屬性裝飾器來實現getter / setter功能。

這就是您可以修改代碼的方式。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

3.2 不規則使用標籤的空格。

PEP 8指南確認Python代碼應始終使用四個空格縮進和使用選項卡。儘管這只是一個沒有標準Python引擎執行的規則。但這是您應該遵循的方式,使您的代碼可管理和無錯誤。

反模式示例:與選項卡混合的空格。

這是一個Python代碼,它持有一個縮進列表和兩個方法的類,一個是使用空格,另一個具有用於縮進的製表符。代碼運行正常,但錯過了PEP 8準則。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

重構:將標籤轉換為空格。

解決方案是重構你的代碼將標籤轉換成空格。有很多方法可以做到。

1.您可以編輯文本編輯器的設置,並將其設置為插入四個空格而不是一個選項卡。

2.如果你在Linux上使用VIM,那麼使用<:retab>命令為你做這個工作。它將與否交換標籤。的標籤設置中定義的空格。

3.您還可以運行腳本<reindent.py>進行自動縮進。您可以在<Python安裝目錄> Tools \ Scripts \ reindent.py>路徑下找到它。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

3.3。Python的異常塊的利用不足

在學習或適應新的語言的同時,我們也考慮走過必需品,然後走過演出。

但是,我們不應該忽略一個例外的話題。瞭解和利用異常可以使您的應用程序工作,即使在特殊情況下。

有時,我們可以使用它們,但是從不會幫助我們。我們來看一個這樣的例子,然後是一個有助於高效實現異常的解決方案。

反模式:根本不使用異常。

下面是一個弱錯誤處理的例子。這只是證實一個明顯的事實。但是忽略了以下條件。

  • 如果“debug.log”存在,但是在刪除它時會出現一些錯誤。該代碼將中止,沒有任何來自應用程序的信息。

  • 您不會希望看到您的代碼死於不影響執行其餘部分的步驟。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

EAFP是Python程序員經常使用的常見俚語。它代表<容易要求寬恕而不是許可>。它表示使用異常處理與未定義的變量或文件等有關的錯誤的概念。

解決方案:使用Try-Except來避免任何可能性。

這是一個封裝在try-except塊中的代碼。現在是按照EAFP慣例的格式。有趣的是,except子句設置為顯示擬合錯誤消息。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

3.4。從函數返回不一致的類型值。

你應該檢查你的函數是否返回一個類型的值,它的調用者不會期望。如果是這樣,那麼更好地更新該條件以引發異常。否則,呼叫者將在進一步處理之前總是必須驗證類型。

你應該避免編寫這樣的代碼,導致混亂,並增加複雜性。考慮下面的例子,並參考下面給出的解決方案。

反模式:返回變體類型。

在下面的示例中,函數get_error_message()返回與錯誤代碼相對應的錯誤消息。但是在不存在的錯誤代碼的情況下,它返回None。它導致難以維護的模糊的代碼。而呼叫者必須明確地檢查它。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

解決方案:提高未知值的異常。

處理意外情況的理想方法是使用try-except塊並提出適當的異常。它也適合這種條件,因為該函數不會返回任何數據。所以不是返回任何無效或未知的值,更好地拋出異常。

您可以參考下面的代碼,這是上面的例子的更新版本。現在它更清潔,不需要檢查額外的數據類型。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

3.5。類型檢查不正確

有時,程序員可以在代碼中調用<type()>來比較數據類型。相反,他們應該使用<isinstance>進行類型檢查。

該方法甚至能夠識別派生類對象。因此,它是類型檢查的最佳選擇。

反模式:弱類型檢查示例。

以下代碼將無法匹配Employee類的<emp>類型。儘管如此,程序員也會認為它會奏效。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

解決方案:強大的類型檢查示例。

這是執行對象類型檢查的正確方法。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

導致循環依賴的import。

在Python中,import也是一個可執行語句。每個import子句導致執行相應的模塊。此外,在相關代碼(在def或類)中執行之前,模塊中嵌入的任何函數或類都不會生效。

因此,遞歸導入模塊可能會導致程序中的循環依賴。例如,假設我們有兩個模塊mod1和mod2。

mod1具有導入調用以加載mod2。它包含以下代碼。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

要理解循環依賴的原因,讓我們想象下面的代碼序列。

1.從主程序加載mod1。主程序然後讀取mod1並處理它。由於它正在加載mod2在頂部,所以Python將繼續閱讀它。

2.直到這一點上,Python的兩個<MOD1>和<MOD2>已經得到了sys.modules中下對象列表。但是,由於Python正在執行<mod2>模塊,<mod1>仍然沒有收到任何定義。

3.現在,為了使循環依賴的情況下,讓我們添加一個“進口MOD1”語句轉換成模2模塊。所以在執行“import mod1”調用時,Python將引用回到空的mod1對象。

4.在這種情況下,任何調用MOD1從mod2的實體(DEF或類)會導致失敗。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

解。

上述問題可能有兩個最有可能的解決方案。

1.修改程序以消除遞歸導入。您可以將一些功能卸載到新模塊。

2.另一種方法可能是將受影響的導入(mod2)替換為調用模塊的尾部(即mod1)。

因此,在模塊mod1中將“import mod2”調用轉移到EOF將會解決循環依賴問題。

5.濫用<__ Init __>方法。

就像C ++中的構造函數一樣,Python中有<__ init __>方法。當Python將內存分配給一個新的類對象時,它會自動調用。此方法的目的是設置類對象的實例成員的值。

並且從<__ init __>方法顯式返回值不是一個好習慣。這意味著你想偏離這種方法的目的。如果是這種情況,那麼最好選擇一種不同的方法,或者定義一個新的實例方法。

讓我們用一些例子來確定上述事實。

示例:濫用<__ Init __>方法。

在此示例中,代碼正在嘗試從<__ init __>方法返回員工的工作經驗。但是會導致錯誤“TypeError:__init __()應返回None”。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

示例:添加新的屬性來修復<__ Init __>錯誤。

為了解決上述問題,我們將把所需的邏輯移至不同的實例方法。一旦類對象準備好初始化,就可以調用此方法。

95%都犯過的錯誤,學完讓你的Python代碼更加的穩定如坦克!

所以這是一些Python編程錯誤和他們的解決方案,我們想與你分享。但是,該列表太大,無法放在一個帖子中。所以我們還會繼續發佈有用的編程錯誤。

總結 - 常見的Python編程錯誤避免。

您好,我們相信這篇文章有很多可供您在日常工作中學習和應用。您可能不會直接使用它們,但您仍然可以避免在代碼中出現此類錯誤。

最後,如果你有任何這樣的“Python編程錯誤”來分享,那麼讓世界知道它。通過閱讀博客和文章,保持有關信息的新鮮度也很重要,PDF的書籍已經整理到了群文件當中,需要的朋友可以加下群

相關推薦

推薦中...