# Python import module 和 from module import * 的差別? :::info 🚀 **30秒重點統整:** 1. **存取方式差異** - `import module` → 使用 `module.function()` 存取模組內功能 - `from module import *` → 可直接使用 `function()`,但來源不明確 2. **命名空間影響** - 前者保持模組獨立命名空間,避免命名衝突 - 後者將所有內容導入當前命名空間,可能覆蓋同名變數或函式 3. **實務建議** - **大型專案**:用 `import module` (清晰、安全) - **特定需求**:用 `from module import func` (只匯入需要的功能) - **避免使用** `from module import *` (除非快速測試腳本) 📌 **經典錯誤範例:** ```python= from math import sqrt sqrt = 3.14 # 原來的 sqrt() 函式被新數值覆蓋 print(sqrt(16)) # 導致 TypeError: 'float' object is not callable ``` ::: 在 Python 中,`import module` 和 `from module import *` 是兩種不同的模組匯入方式,它們的差異主要體現在作用域、程式碼可讀性和命名衝突風險上。 ### 1. `import module` 這種匯入方式會將整個模組匯入到目前的命名空間中,但模組內的函式、類別和變數都需要透過模組名稱前綴來存取。例如: ```python= import math print(math.sqrt(16)) # 使用模組名稱作為前綴 ``` #### 特點: - **作用域清楚**:所有的函式和變數都屬於 `module`,避免命名衝突。 - **程式碼可讀性高**:透過模組名稱前綴,可以清楚地知道某個函式或變數來自哪個模組。 - **適合大型專案**:尤其是當多個模組中存在相同名稱的函式或變數時,使用這種方式可以避免混淆。 --- ### 2. `from module import *` 這種匯入方式會將模組中的所有函式、類別和變數直接匯入到目前的命名空間中,因此可以直接使用它們,而不需要模組名稱前綴。例如: ```python= from math import * print(sqrt(16)) # 不需要模組名稱前綴 ``` #### 特點: - **簡化程式碼**:可以直接使用模組中的函式或變數,程式碼更簡潔。 - **容易引發命名衝突**:如果目前的作用域中已經有相同名稱的函式或變數,會覆蓋原來的定義。例如: ```python= from math import * def sqrt(x): return x # 自訂的函式會覆蓋 math模組的sqrt print(sqrt(16)) # 輸出 16,而不是 4 ``` - **不建議使用**:由於難以追蹤變數或函式的來源,這種方式不利於程式碼的可讀性與維護。 📌 **經典錯誤範例:** ```python= from math import sqrt sqrt = 3.14 # 原來的 sqrt() 函式被新數值覆蓋 print(sqrt(16)) # 導致 TypeError: 'float' object is not callable ``` :::spoiler **經典錯誤範例解析**: #### 💥 **發生什麼事?** 1. **匯入 `sqrt` 函式**: - `from math import sqrt` 把 `math.sqrt` 函式匯入到當前命名空間。 - 這時,`sqrt` 是一個函式,用於計算平方根。 2. **重新定義 `sqrt`**: - 後續程式直接賦值:`sqrt = 3.14`。 - 此操作覆蓋了之前的 `sqrt` 函式,現在 `sqrt` 是一個浮點數變數 (值為 3.14)。 3. **函式調用錯誤**: - `print(sqrt(16))` 試圖將 `sqrt` 當作函式調用,但此時 `sqrt` 是數值類型(浮點數)。 - 結果觸發錯誤: ```plaintext TypeError: 'float' object is not callable ``` #### 🔥 **為什麼會發生這樣的錯誤?** - 使用 `from module import *` 或直接匯入單一函式時,匯入的內容會直接進入當前命名空間。 - 當前命名空間的任何變數或函式,如果名稱與匯入內容重複,會覆蓋匯入的內容。 - 這種情況容易發生,特別是在命名不嚴謹的情況下。 #### ⭐️ **正確的作法:** ```python= import math # 或 from math import sqrt as math_sqrt sqrt = 3.14 # 不會影響 math.sqrt() print(math.sqrt(16)) # 安全地調用平方根函數,輸出 4.0 ``` ::: --- ### 總結 - **使用情境**: - 若想避免命名衝突並維持程式碼的清晰性,建議使用 `import module`。 - 如果只需要模組中的部分功能,可以使用 `from module import specific_function`,例如: ```python= from math import sqrt, pi print(sqrt(16)) print(pi) ``` - 不建議使用 `from module import *`,除非在互動式環境或快速測試腳本中使用,且確保不會引發命名衝突。