
在程式設計的世界中,變數 (Variables) 是儲存與操作數據的基石。不同於 C 或 Java 等靜態語言將變數視為「容器」,Python 將變數視為「標籤」或「參照 (Reference)」。這種設計賦予了 Python 極大的靈活性與動態特性,但也帶來了初學者容易混淆的記憶體管理觀念。
本章將帶您深入探索 Python 變數的底層機制、四大核心資料型別,以及業界標準的命名規範與最佳實踐。
1. 變數的本質:是容器還是標籤?
在 Python 中,當我們執行 x = 10 時,實際上發生了以下三個步驟:
- 建立物件:在記憶體中建立一個整數物件
10。 - 建立變數:在當前命名空間 (Namespace) 中建立變數名
x。 - 建立連結:將
x指向 (Reference) 記憶體中的物件10。
這與傳統語言的「將值放入盒子」的概念截然不同。理解這一點,對於掌握 Python 的可變 (Mutable) 與不可變 (Immutable) 物件至關重要。
記憶體模型視覺化
在上圖中,若我們執行 y = x,並不會複製物件 10,而是讓 y 也指向同一個物件 10。這就是 Python 的 共享參照 (Shared Reference) 機制。
物件身分與類型查詢
Python 提供了兩個強大的內建函數來檢視變數的狀態:
type(x): 回傳物件的資料型別。id(x): 回傳物件在記憶體中的唯一識別碼 (記憶體位址)。
x = 10
y = x
print(f"x 的值: {x}, ID: {id(x)}")
print(f"y 的值: {y}, ID: {id(y)}")
# 修改 x 的值
x = 20
print(f"修改後 x 的 ID: {id(x)}")
print(f"y 的 ID 仍為: {id(y)}")
2. Python 四大核心資料型別
Python 是一門強型別 (Strongly Typed) 且動態型別 (Dynamically Typed) 的語言。這意味著變數本身沒有型別,物件才有型別,且型別檢查是在執行期進行的。
主要的基礎資料型別包括:
| 型別名 (Type) | 描述 (Description) | 範例 (Example) | 可變性 (Mutability) |
|---|---|---|---|
| int | 整數,無長度限制 | 42, -10, 999999999 | Immutable |
| float | 浮點數,雙精度 | 3.14, 1.2e-3, -0.001 | Immutable |
| str | 字串,Unicode 序列 | "Hello", 'Python' | Immutable |
| bool | 布林值,邏輯判斷 | True, False | Immutable |
2.1 整數 (int) 與浮點數 (float)
Python 的整數設計非常強大,它會自動處理溢位問題,支援任意大小的整數(僅受限於記憶體)。浮點數則遵循 IEEE 754 標準。
# 大數運算
big_num = 2 ** 100
print(f"2 的 100 次方: {big_num}")
# 浮點數精度問題
f1 = 0.1 + 0.2
print(f"0.1 + 0.2 = {f1}") # 輸出 0.30000000000000004
注意:浮點數運算存在精度誤差,若涉及金融計算,建議使用
decimal模組。
2.2 字串 (str) 的奧秘
字串是 Python 中最強大的序列型別之一。它支援豐富的操作方法,如切片 (Slicing)、格式化 (Formatting) 與串接。
字串切片與索引
text = "Python Programming"
print(text[0]) # 取第一個字元 'P'
print(text[-1]) # 取最後一個字元 'g'
print(text[0:6]) # 取索引 0 到 5 'Python'
print(text[::-1]) # 字串反轉 'gnimmargorP nohtyP'
2.3 布林值 (bool) 與邏輯
布林值只有 True 和 False 兩個狀態,是控制程式流程的核心。值得注意的是,Python 中許多「空」或「零」的值在布林情境下會被視為 False:
0,0.0""(空字串)[](空列表),{}(空字典)None
3. 型別轉換 (Type Casting)
在處理使用者輸入或不同來源的數據時,型別轉換是必備技能。Python 提供了顯式轉換函數。
常見轉換場景
# 字串轉整數
age_str = "25"
age_int = int(age_str)
# 數值轉字串
pi = 3.14159
pi_str = str(pi)
# 布林轉換
is_exist = bool("有些內容") # True
is_empty = bool("") # False
隱式轉換 (Implicit Conversion)
在某些運算中,Python 會自動進行型別提升 (Type Promotion),例如整數與浮點數運算時,結果會自動轉為浮點數。
result = 10 + 3.14 # 13.14 (float)
4. 變數命名規範與最佳實踐
編寫清晰、可讀的程式碼是專業開發者的基本素養。Python 社群遵循 PEP 8 風格指南。
命名規則 (Naming Convention)
| 項目 | 規則 | 範例 | 不推薦 |
|---|---|---|---|
| 變數 | Snake Case (小寫+底線) | user_name, total_count | userName, TotalCount |
| 常數 | Upper Snake Case (全大寫) | MAX_CONNECTIONS, PI | maxConnections, Pi |
| 類別 | Pascal Case (大寫開頭) | UserProfile, Car | user_profile, car |
| 私有變數 | 前綴底線 | _internal_var | internalVar |
型別註釋 (Type Hints)
自 Python 3.5 起,引入了型別註釋功能。雖然 Python 執行期不會強制檢查,但這對於大型專案開發、IDE 自動補全與靜態分析(如 mypy)極有幫助。
# 使用型別註釋
def calculate_area(radius: float) -> float:
PI: float = 3.14159
return PI * (radius ** 2)
user_age: int = 30
user_name: str = "Alice"
5. 深入探討:動態型別的優缺點
Python 的動態型別特性是一把雙面刃。理解其特性有助於寫出更穩健的程式碼。
優點
- 開發速度快:無需繁瑣的型別宣告,程式碼更簡潔。
- 靈活性高:同一個變數可以重新指向不同型別的物件(雖然不建議這樣做)。
- 泛型程式設計容易:函數可以接受任何支援特定操作的物件(Duck Typing)。
缺點
- 執行期錯誤:型別錯誤 (TypeError) 往往在執行時才會爆發。
- 效能開銷:直譯器需要在執行期檢查型別,增加了運算成本。
- 可讀性挑戰:在缺乏型別註釋的情況下,閱讀大型程式碼庫可能較困難。
解決方案:靜態分析
使用 mypy 等工具可以在執行前檢查型別錯誤,結合了動態語言的靈活性與靜態語言的安全性。
# 安裝 mypy
pip install mypy
# 執行檢查
mypy script.py
6. 常見問題 (FAQ)
Q1: 為什麼 0.1 + 0.2 不等於 0.3?
A: 這是因為電腦使用二進位制來儲存浮點數,無法精確表示某些十進位小數(如 0.1)。這會導致微小的精度誤差。若需要高精度計算,請使用 decimal 模組或 fractions 模組。
Q2: is 和 == 有什麼區別?
A:
==比較的是 值 (Value) 是否相等。is比較的是 身分 (Identity),即是否指向記憶體中同一個物件(比較id())。 通常比較數值用==,比較None或單例物件用is。
Q3: 什麼是 Python 中的「可變」與「不可變」物件?
A:
- 不可變 (Immutable):物件建立後內容無法修改。例如
int,float,str,tuple。修改這些變數實際上是建立新物件並重新指向。 - 可變 (Mutable):物件內容可以原地修改。例如
list,dict,set。
7. 總結
在本章中,我們深入剖析了 Python 變數與資料型別的核心機制。從底層的記憶體模型到上層的命名規範,這些知識將是您未來撰寫高品質 Python 程式碼的基石。
本章重點回顧:
- 變數是記憶體中物件的「標籤」。
- 掌握四大基本型別:
int,float,str,bool。 - 理解並善用型別轉換。
- 遵循 PEP 8 命名規範,提升程式碼可讀性。
- 使用型別註釋 (Type Hints) 增強程式碼健壯性。
在下一章中,我們將學習 控制結構 (Control Structures),讓程式具備判斷與邏輯思考的能力,敬請期待!
延伸閱讀: