常見的 Python 錯誤以及如何避免它們

2024年10月04日08:43:04 科技 1425

常見的 Python 錯誤以及如何避免它們 - 天天要聞

1 濫用可變默認參數

Python 中最常見和最微妙的錯誤之一涉及在函數中使用可變默認參數。這可能會導致難以調試的意外行為。

錯誤

在定義函數時,可能想使用可變數據類型(如列表或字典)作為默認參數。下面是一個典型的示例:

def add_item(item, item_list=[]):
    item_list.append(item)
    return item_list

乍一看,這個函數似乎很簡單:它向列表中添加一個項目並返回更新的列表。但是,多次調用此函數時可能會產生意外結果:

print(add_item(1))  # Output: [1]
print(add_item(2))  # Output: [1, 2]
print(add_item(3))  # Output: [1, 2, 3]

可能希望每次調用 add_item 都會返回一個僅包含新項的列表,但相反,它會累積來自先前調用的項。

為什麼會這樣

在 Python 中,默認參數值僅在定義函數時計算一次,而不是每次調用函數時計算。這意味着,如 果使用 list 等可變對象作為默認值,則對該函數的所有調用都共享同一對象。

解決方案

要避免此問題,請使用 None 作為默認值,然後根據需要在函數內創建一個新列表:

def add_item(item, item_list=None):
    if item_list is None:
        item_list = []
    item_list.append(item)
    return item_list

現在,對 add_item 的每次調用都將按預期運行:

print(add_item(1))  # Output: [1]
print(add_item(2))  # Output: [2]
print(add_item(3))  # Output: [3]

最佳實踐

使用可變對象作為默認參數時,請始終保持謹慎。如果默認值需要可變,請考慮使用 None 並在函數內初始化對象。

2 忘記關閉文件

文件處理是 Python 中的一項常見任務,但如您在打開文件後忘記關閉文件,則可能會遇到內存泄漏或文件鎖定等問題。

錯誤

當在 Python 中打開文件時,完成後將其關閉至關重要。下面是開發人員可能忘記這樣做的示例:

file = open('example.txt', 'r')
content = file.read()
# Forgot to close the file

忘記關閉文件可能會導致問題,尤其是在處理多個文件或循環處理文件時。

為什麼會這樣

Python 會保留對文件的引用,直到它被顯式關閉或程序終止。如果忘記關閉文件,文件描述符將保持打開狀態,這可能會導致資源泄漏。

解決方案

在 Python 中處理文件的最佳方法是使用 with 語句,該語句在執行代碼塊後自動關閉文件:

with open('example.txt', 'r') as file:
    content = file.read()

這可確保文件正確關閉,即使塊中發生異常也是如此。

最佳實踐

在處理文件時,請始終使用 with 語句。它更簡潔、更具可讀性,並防止您意外地打開文件。

令人困惑的==和is

在 Python 中,==is 經常被初學者錯誤地互換使用,從而導致難以診斷的錯誤。

錯誤

a = [1, 2, 3]
b = [1, 2, 3]

print(a == b)  # Output: True
print(a is b)  # Output: False

此處,a == b 返回 True,因為 ab 的內容相等。但是,a is b 返回 False,因為 is 檢查對象標識,這意味着它會檢查 ab 是否引用內存中的同一對象。

為什麼會這樣

== 檢查兩個對象的值是否相等,而 is 檢查兩個引用是否指向同一個對象。初學者經常將兩者混淆,使用 is 是指檢查是否相等。

解決方案

為避免混淆,請記住:

  • 使用 == 比較對象的值。
  • Use 檢查兩個引用是否指向同一個對象(例如,與 None 進行比較時)。

最佳實踐

了解 ==is 之間的區別。使用 == 來比較值,用於比較對象標識,尤其是在處理字符串、整數和元組等不可變類型時。

3 誤解 Python 的範圍規則

了解 Python 的範圍規則對於避免在函數、循環和條件中處理變量時出現意外行為至關重要。

錯誤

def outer_function():
    x = 10
    def inner_function():
        print(x)
    inner_function()

outer_function()  # Output: 10

在這種情況下,inner_function可以從變量 x 的封閉outer_function訪問變量 x。但是,當嘗試修改變量時,事情會變得更加棘手:

def outer_function():
    x = 10
    def inner_function():
        x += 1
        print(x)
    inner_function()

outer_function()  # Raises UnboundLocalError

在這裡,嘗試在 inner_function 中修改 x 會引發 UnboundLocalError,因為 Python 將 x 視為 inner_function 中的局部變量(由於賦值),但它尚未在該局部範圍內初始化。

為什麼會這樣

Python 有一組定義明確的規則來解析變量,稱為 LEGB 規則:Local、Enclosing、Global 和 Built-in。當為函數中的變量賦值時,除非另有明確說明,否則 Python 會假定它是局部變量。

解決方案

要在內部函數中修改外部作用域的變量,可以使用 nonlocal 關鍵字(用於封閉作用域)或 global(用於全局作用域):

def outer_function():
    x = 10
    def inner_function():
        nonlocal x
        x += 1
        print(x)
    inner_function()

outer_function()  # Output: 11

使用 nonlocal,您可以修改封閉範圍內的變量,而不會導致錯誤。

最佳實踐

了解並遵守 Python 的範圍規則。使用 nonlocal 修改封閉範圍內的變量,使用 global 修改全局變量。避免不必要的全局變量,以降低複雜性和潛在錯誤。

科技分類資訊推薦

亮銀懸浮框與冷頭屏相得益彰,Ocypus 正式推出 Sigma L PRO 水冷 - 天天要聞

亮銀懸浮框與冷頭屏相得益彰,Ocypus 正式推出 Sigma L PRO 水冷

IT之家 7 月 4 日消息,出海品牌 Ocypus 隱翅蟲正式推出此前曾在 COMPUTEX 2025 台北國際電腦展上亮相的 Sigma L PRO 水冷。其包含 240 和 360 兩種規格版本,標稱解熱能力 TDP 分別為 290W 和 310W。Sigma L PRO 系列一體式水冷散熱器的最大特色之處無疑是冷頭裝飾設計:亮銀色框架從水泵上方殼層跨
原價3500元的安卓智能屏,如今二手300塊,自帶7寸雙屏 - 天天要聞

原價3500元的安卓智能屏,如今二手300塊,自帶7寸雙屏

今天寫個有意思的東西,我在半年前就發現了它,那時候商家庫存剛流入閑魚。我覺得有點貴,自作聰明想等商家賣上一陣子,個人用戶玩膩後再轉賣,把價格打下來,結果到今天也沒降多少。首先說下它是啥?這是飛利浦VTR9800視頻會議智能終端一體機,官網全
疑似華為Mate 80系列回歸直屏:頂配版還有雙層OLED - 天天要聞

疑似華為Mate 80系列回歸直屏:頂配版還有雙層OLED

【TechWeb】6月11日,華為在年度新品發佈會上正式推出了Pura 80系列手機。作為華為旗艦產品線的最新成員,這一系列以「先鋒影像美學」為核心,重新定義了移動影像的可能性,一經亮相便受到了外界的廣泛關注。而在不久前,華為另一當家系列——Mate系列也有新成員迎來曝光。現在有最新消息,近日有數碼博主疑似帶來了新一代...
崑崙芯科技完成新一輪融資,華興擔任獨家財務顧問|華興交易 - 天天要聞

崑崙芯科技完成新一輪融資,華興擔任獨家財務顧問|華興交易

近日,國產AI芯片領軍企業崑崙芯(北京)科技有限公司(以下簡稱「崑崙芯」)完成新一輪股權融資。華興資本旗下華興證券擔任本輪獨家財務顧問。崑崙芯P800渲染圖崑崙芯是業界領先的人工智能芯片供應商。公司專註打造「更快、更強、更省」的智能計算產品,在芯片架構、集群系統、軟件生態領域具備深厚技術積累和全棧競爭優勢...
小米YU7紙巾盒賣169元被指太貴 雷軍回應 - 天天要聞

小米YU7紙巾盒賣169元被指太貴 雷軍回應

【TechWeb】7月4日消息,隨着小米YU7的正式上市,配套的Xiaomi Life車載磁吸紙巾盒也在小米汽車App商城上架,然而,這一定價也引發了部分網友質疑。對此,雷軍在直播中首次回應了定價問題,解釋了紙巾盒成本的原因。雷軍指出,紙巾盒的材質和製作工藝都非常複雜,最初的設計未能通過車規測試,後來才做出了材質和膠水的調整...