文章目錄
- Python 中的可變對象與不可變對象
- 不可變對象(Immutable Objects)
- 可變對象(Mutable Objects)
- 重要區別
Python 中的可變對象與不可變對象
在 Python 中,對象可以分為可變對象(mutable)和不可變對象(immutable),這是 Python 中非常重要的概念,影響著對象的賦值、傳遞和修改行為。
不可變對象(Immutable Objects)
不可變對象是指創建后不能被修改的對象。如果嘗試修改,實際上是創建了一個新對象。
常見的不可變類型:
- 數字類型:
int
,float
,bool
- 字符串:
str
- 元組:
tuple
- 凍結集合:
frozenset
示例:
# 整數是不可變的
x = 10
print(id(x)) # 打印內存地址
x += 1
print(id(x)) # 內存地址改變,是新對象# 字符串是不可變的
s = "hello"
print(id(s))
s += " world"
print(id(s)) # 新字符串對象# 元組是不可變的
t = (1, 2, 3)
try:t[0] = 100 # 嘗試修改元組的第一個元素
except TypeError as e:print(e) # 輸出錯誤信息(TypeError)
特別注意:
盡管元組本身是不可變的,但如果元組中包含可變對象,如列表,這些可變對象內部的內容是可以被修改的。這種情況下,元組的不可變性只適用于頂層結構,不影響內部元素的可變性。
tup = (1, [2, 3], 4)
tup[1].append(5) # 修改元組中的列表
print(tup) # 輸出 (1, [2, 3, 5], 4)
可變對象(Mutable Objects)
可變對象是指創建后可以被修改的對象,修改時內存地址不變。
常見的可變類型:
- 列表:
list
- 字典:
dict
- 集合:
set
- 字節數組:
bytearray
- 用戶自定義的類實例
示例:
# 列表是可變的
lst = [1, 2, 3]
print(id(lst)) # 打印內存地址
lst.append(4)
print(id(lst)) # 內存地址不變# 字典是可變的
d = {'a': 1}
print(id(d))
d['b'] = 2
print(id(d)) # 內存地址不變# 集合是可變的
st = {1, 2, 3}
print(id(st))
st.add(4)
st.remove(3)
print(id(st))
重要區別
-
賦值與修改:
# 不可變對象 a = 1 b = a b = 2 # a不變# 可變對象 x = [1, 2] y = x y.append(3) # x也被修改
-
函數參數傳遞:
- 不可變對象作為參數時,函數內修改不會影響原值
- 可變對象作為參數時,函數內修改會影響原值
def modify(num, lst):num += 1lst.append(4)n = 10 l = [1, 2, 3] modify(n, l) print(n) # 輸出10,不變 print(l) # 輸出[1, 2, 3, 4],被修改
-
字典鍵的限制:
- 只有不可變對象可以作為字典的鍵
- 可變對象不能作為字典的鍵
d = {} d['key'] = 'value' # 字符串鍵,合法 d[1] = 'number' # 整數鍵,合法 d[(1, 2)] = 'tuple' # 元組鍵,合法# d[[1, 2]] = 'list' # 報錯,列表不能作為鍵
-
集合元素的限制:
盡管集合是可變的,但也有一些操作上的限制。例如,集合只能包含不可變(可哈希)的對象。因此不能將列表或另一個集合作為元素添加到集合中。nested_set = {1, 2, 3} try:nested_set.add([4, 5, 6]) # 嘗試添加列表到集合中# nested_set.add({7, 8, 9}) # 嘗試添加另一個集合到集合中 except TypeError as e:print(e) # 輸出錯誤信息
理解可變和不可變對象的區別對于編寫正確、高效的 Python 代碼非常重要,特別是在處理對象傳遞和共享狀態時。