---
# System prepended metadata

title: Python import module 和 from module import * 的差別？
tags: [Python]

---

# 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 *`，除非在互動式環境或快速測試腳本中使用，且確保不會引發命名衝突。
