Python中多目標賦值及共享引用的問題
阿新 • • 發佈:2018-11-23
多目標賦值語句就是直接把所有提供的變數名都賦值給右側的物件。
>>> a = b = c = "spam" # 將字串"spam"同時賦值給a,b,c
>>> a,b,c
('spam', 'spam', 'spam')
>>>
上面的語句相當於下面的簡單賦值
>>> c = "spam"
>>> b = c
>>> a = b
>>> a, b, c
('spam', 'spam', 'spam')
>>>
在這裡只有一個物件,由三個變數共享,全部指向記憶體內同一個物件。這種賦值存在的問題就是:
i. 如果右邊的值是不可變物件,修改其中一個變數,不影響其他變數
>>> a = b = 100 # 不可變物件
>>> b += 1 # 改變其中一個值
>>> a, b # 不會影響另外變數的值
(100, 101)
>>>
ii. 如果右邊的值是可變物件,修改其中一個變數,會影響其他變數
>>> a = b = [] # 同時將可變物件,列表,賦值給a,b >>> id(a);id(b) # 可以看出,兩個變數的id號是一樣的 37796680 37796680 >>> b.append(42) # 對其中的變數做修改,會原地修改物件 >>> a,b # a,b兩個變數同時變化 ([42], [42]) >>>
iii.要避免上面的問題,可以單獨賦值來避免
>>> a = []
>>> b = []
>>> id(a);id(b) # 單獨賦值的話,兩者的id號不同
37796360
37811720
>>> b.append(42) # 原地修改其中一個變數,不會影響另外一個變數
>>> a,b
([], [42])
>>>
iv. 或者使用深淺拷貝避免
>>> import copy >>> a = [] >>> b = copy.copy(a) # 通過淺拷貝來賦值 >>> id(a);id(b) 39263368 37796680 >>> b.append(42) >>> a, b ([], [42]) >>>
iiv. 或者使用[:]來避免
>>> a = []
>>> b = a[:]
>>> a, b
([], [])
>>> id(a),id(b)
(37796360, 37811720)
>>> b.append(42)
>>> a,b
([], [42])
>>>