1. 程式人生 > >Python中多目標賦值及共享引用的問題

Python中多目標賦值及共享引用的問題

多目標賦值語句就是直接把所有提供的變數名都賦值給右側的物件。 

>>> 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])
>>>