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

 

你可能感兴趣的:(【编程语言】)