模塊 10: 常見陷阱
從 JavaScript 開發者視角,解析 Python 中常見的概念陷阱和易錯點。
1. 引言
當你從一種語言切換到另一種時,最棘手的往往不是新語法,而是一些看似相同但行為卻截然不同的“陷阱”。這些細微的差異可能會導致難以察覺的 bug 和困惑。
本模塊專門為你——從 JavaScript 過渡到 Python 的開發者——梳理了一些最常見的概念陷阱。
💡 學習策略:不要死記硬背。理解每個陷阱背後的“為什麼”,並將其與 JavaScript 的行為進行對比,這樣你才能在實際編碼中自然而然地避開它們。
2. 真值 (Truthy) 與假值 (Falsy)
在 Python 中,空的集合類型(如列表、字典、元組)被認為是“假值”(Falsy)。這與 JavaScript 的行為有顯著不同,在 JS 中,空數組 [] 和空對象 {} 都是“真值”(Truthy)。
3. this vs self
在 JavaScript 的類方法中,this 是一個關鍵字,其指向在函數調用時確定。而在 Python 的實例方法中,第一個參數(按照慣例命名為 self)顯式地代表實例本身,它不是一個關鍵字。
4. 變量作用域
JavaScript (ES6+) 擁有塊級作用域(由 {} 界定),而 Python 的作用域是基於函數(或類、模塊)的。在 for 循環等代碼塊中定義的變量,在 Python 中會“洩漏”到外部作用域。
5. 可變默認參數
這是一個 Python 中非常經典且臭名昭著的“陷阱”。如果函數的默認參數是一個可變對象(如列表或字典),那麼這個對象會在所有調用之間共享。這與 JavaScript 的行為完全不同。
6. null/undefined vs None
JavaScript 中有兩個表示“無”的值:null(表示“有意設置的空值”)和 undefined(表示“未定義”)。在 Python 中,只有一個對應的概念:None。
7. 循環變量捕獲 (Loop Variable Capture)
這是 Python 作用域規則的一個副作用,常發生在閉包或 lambda 函數中。
8. 賦值 vs 拷貝 (Assignment vs Copying)
在 Python 中,賦值語句 (=) 永遠不會複製對象,它只是創建了一個新的引用(別名)。這與 JavaScript 的對象賦值行為一致,但對於習慣了某些 C++ 行為的開發者來說可能是個陷阱。
8. 總結
理解並掌握這些差異,將幫助你更快地寫出健壯、無意外的 Python 代碼。當你遇到意料之外的行為時,不妨回過頭來看看這個列表,檢查是否踩中了其中的某個“陷阱”。