Python 資料模型 (Data Model)
Python 的資料模型 (Data Model) 定義了物件在語言中的行為方式。在 Python 中,萬物皆物件 (Everything is an object),這句話是理解 Python 的關鍵。
物件的三要素
每個 Python 物件都有三個核心特性:
- 識別碼 (Identity)
- 型別 (Type)
- 值 (Value)
1. 識別碼 (Identity)
識別碼可以想像成物件在記憶體中的地址。一旦物件被建立,其識別碼就不會改變。
使用 id() 函數可以查看物件的識別碼:
x = 100
print(id(x)) # 例如: 4309854320
y = x
print(id(y)) # 與 x 相同,因為指向同一個物件
使用 is 運算子就是在比較兩個物件的識別碼是否相同:
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True (值相同)
print(a is b) # False (是不同的物件)
print(a is c) # True (指向同一個物件)
2. 型別 (Type)
型別決定了物件支援哪些操作(例如長度、加法等)以及它可以儲存什麼值。
使用 type() 函數可以查看物件的型別:
print(type(10)) # <class 'int'>
print(type("Hello")) # <class 'str'>
print(type([1, 2])) # <class 'list'>
3. 值 (Value)
值是物件儲存的數據。根據值是否可以改變,物件分為可變 (Mutable) 與不可變 (Immutable)。
- 不可變物件:建立後值不能改變(如
int,str,tuple)。 - 可變物件:建立後值可以改變(如
list,dict,set)。
特殊屬性 (Special Attributes)
Python 物件通常包含一些以雙底線開頭和結尾的特殊屬性(唯讀或可寫),這些屬性儲存了物件的元數據 (metadata)。
__name__
__name__ 屬性儲存模組、類別、函數、方法等物件的名稱。
def my_function():
pass
class MyClass:
pass
print(my_function.__name__) # my_function
print(MyClass.__name__) # MyClass
print(str.__name__) # str
對於模組來說,__name__ 特別重要。當模組被直接執行時,__name__ 會是 "__main__";當被匯入時,則是模組名稱。
__doc__
__doc__ 屬性儲存物件的文件字串 (Docstring)。
def square(x):
"""計算並回傳 x 的平方"""
return x * x
print(square.__doc__)
# 計算並回傳 x 的平方
__dict__
__dict__ 屬性是一個字典,儲存了物件的可寫入屬性。這也是 Python 實現動態屬性的核心機制。
class Person:
def __init__(self, name):
self.name = name
p = Person("Alice")
print(p.__dict__) # {'name': 'Alice'}
# 動態新增屬性其實就是加入到 __dict__ 中
p.age = 25
print(p.__dict__) # {'name': 'Alice', 'age': 25}
__module__
__module__ 屬性儲存定義該類別或函數的模組名稱。
from datetime import date
print(date.__module__) # datetime
__class__
__class__ 屬性指向產生該實例的類別(即物件的型別)。
x = 10
print(x.__class__) # <class 'int'>
# 等同於 type(x)
特殊方法 (Magic Methods)
Python 資料模型的一大特色是使用特殊方法(如 __init__, __str__, __len__ 等)來定義物件的行為。這些方法讓自訂物件可以像內建型別一樣運作(例如支援 + 運算子或 len() 函數)。
詳細內容請參考 特殊方法 (Magic Methods)。
物件管理的最佳實踐
- 善用
is和==:比較None時使用is None,比較值相等時使用==。 - 理解可變性:避免使用可變物件(如 list)作為函數的預設參數。
- 查閱文件:善用
__doc__或help()來了解物件的用途。