Python 初學者常犯的5個錯誤,布林型竟是整型的子類
作者:Mohit
機器之心編譯
參與:思
Python 是一種神奇的語言,看似簡單便捷,但總會有一些意想不到的驚喜在等著我們。比如說,assert 在正式環境下根本不會執行,isinstance(False, int) 竟然輸出 True。
Python 是一種高階的動態程式語言,它以易於使用著名。目前 Python 社群已經非常完善了,近幾年它的發展尤為迅猛。但是易於使用同樣能帶來一些壞處,即易於誤用。在本文中,作者列舉了 5 個初學者常犯的錯誤,希望它們能幫助初學者寫更加正確與優美的程式碼。
1. 可變的預設引數
Python 中的預設引數會在執行函式定義時計算一次,這表示在函式完成定義後該表示式只執行一次,因此預設值可以用於後續的每一次呼叫。如果我們令預設引數為可變的,例如列表或字典等,那麼對於將來所有的呼叫,該引數都是一直保留且可變的。
如下為不正確的表達方式,如果我們第一次呼叫 add_item 增加「a」時,items=[『a』]。當我們第二次呼叫 add_item 增加「b」時,由於定義中的 items=[] 只在初始化的時候執行一次,因此這時的 items=[『a』, 『b』]。
尤其是當我們在呼叫 add_item 函式時沒傳入任何引數,那麼 items 還是能保留以前記住的內容,相當於將以前的內容洩漏給了後續的呼叫。
def add_item(new_item, items=[]):
items.append(new_item)
正確的表達方式應該是如下,在我們沒傳入 items 時應該要將它初始化為空白列表:
def add_item(new_item, items=None):
if items is None:
items = []
items.append(new_item)
2. 將 assert 宣告語句作為保證條件
因為 assert 語句很容易檢查一些條件是否滿足或執行是否正確,開發者經常用它來檢查某部分程式碼的有效性。但是當 Python 直譯器呼叫時帶了-O (optimize) flag,那麼 assert 語句會從位元組碼中移除。所以,如果 assert 語句在面向使用者驗證的產品程式碼中,根本就不會執行,因為它可能會造成一些安全漏洞。
因此開發者應該只在測試中使用 assert 語句,不正確的示例如下:
assert re.match(VALID_ADDRESS_REGEXP, email) is not None
正確的程式碼要改成:
if not re.match(VALID_ADDRESS_REGEXP, email):
raise AssertionError
3. 使用 isinstance 代替 type
type 和 isinstance 都能檢查某個物件的類別是什麼。但是它們間有非常重要的區別,isinstance 在解析目標型別時,它會關注繼承關係,而 type 並不會。正因為這個區別,isinstance 在某些時候並不是我們所想的那樣。例如以下案例:
def which_number_type(num):
if isinstance(num, int):
print('Integer')
else:
raise TypeError('Not an integer')
which_number(False) # prints 'Integer', which is incorrect
因為布林型別的變數在 Python 中是 int 的子類,isinstance(num, int) 同樣會得出 True,這並不是我們想要的。在特定的類別中,使用 type 可能更加正確。
4. 不必要的 lambda 表示式
函式在 Python 中是最常用的結構,我們能將函式賦值給某個變數,並將該變數作為引數傳遞給另外一個函式,這也是函式常見的用法。但這對於初學者或瞭解其它程式語言的開發者而言,這種傳遞方式是非常反直覺的。
一個比較常見的模式可以表示為:
def request(self, method, **kwargs):
# ...
if method not in ("get", "post"):
req.get_method = lambda: method.upper()
# ...
上面採用匿名函式 lambda 的方式,最好可以改成以下:
def request(self, method, **kwargs):
# ...
if method not in ("get", "post"):
req.get_method = method.upper
# ...
5. NotImplemented錯誤。這種命名可能會使開發者感到困惑,NotImplementedError 是一種 exception 類,當派生類需要重寫某個方法時,Python 應該觸發這類錯誤。而 NotImplemented 是一個常量,它用於實現二進位制操作。當我們觸發 NotImplemented 時,Python 會給出「TypeError」的報錯。
錯誤的例子:
class SitesManager(object):
def get_image_tracking_code(self):
raise NotImplemented
正確表達方法應該是:
class SitesManager(object):
def get_image_tracking_code(self):
raise NotImplementedError
原文連結:https://deepsource.io/blog/python-common-mistakes/
- END -
如果看到這裡,說明你喜歡這篇文章,請轉發、點贊。掃描下方二維碼或者微信搜尋「perfect_iscas」,新增好友後即可獲得10套程式設計師全棧課程+1000套PPT和簡歷模板,向我私聊「進群」二字即可進入高質量交流群。
↓掃描二維碼進群↓
喜歡文章,點個在看
相關文章
- python開發者常犯的10個錯誤Python
- Solidity語言學習筆記————10、布林型、整型Solid筆記
- Python開發人員常犯的幾個重大錯誤Python
- 企業選型作業上常犯的一個錯誤
- 使用者研究過程中常犯的10個錯誤
- 【盤點】Python新手入門常犯的錯誤!Python
- Python 初學者容易踩的 5 個坑Python
- java布林型別易錯點Java型別
- [譯] 我在程式設計初級階段常犯的錯誤程式設計
- Java初學者容易犯的程式碼錯誤Java
- 編寫 SQL 程式碼時常犯的九個錯誤SQL
- PHP初學者最常遇到的8個錯誤及解決方法PHP
- Python基本資料型別:布林型別(Boolean)Python資料型別Boolean
- 使用 @Transactional 時常犯的N種錯誤
- 令C/C++初學者頭疼,5個常見C/C++錯誤C++
- Java初學者容易犯哪些錯誤?Java
- TypeScript 布林型別TypeScript型別
- 把一個任意型別的值轉換為布林型別型別
- 【譯】Go 專案開發裡最常犯的 10 個錯誤Go
- 寫給初學者的Linux errno 錯誤碼機制Linux
- 10個資料科學家常犯的程式設計錯誤(附解決方案)資料科學程式設計
- go語言初學者常見錯誤Go
- python 判斷一個表示式是什麼布林型別bool()Python型別
- 5.注意Dart中的布林值Dart
- 使用 Spring Framework 時常犯的十大錯誤SpringFramework
- (網頁)Java程式設計師們最常犯的10個錯誤(轉)網頁Java程式設計師
- 5個需要避免的CSS錯誤CSS
- C#快速入門教程(10)——布林型別與布林運算C#型別
- 布林型盲注 時間型盲注
- 產品經理常犯的十大頂級錯誤
- 為初學者準備的 ln 命令教程(5 個示例)
- python類的子類Python
- python 類的子類Python
- 初學者入門大資料,學習Hadoop的5個理由大資料Hadoop
- python中if條件語句對於布林值和非布林值的判斷結果Python
- Python初學者的29個知識難點彙總Python
- 什麼是整型型別?Python整型詳細介紹型別Python
- java開發管理者們常犯之錯誤與解決辦法Java