从多目标赋值语句谈可变和不可变数据类型

前言

很多人一定这样玩过,比如我们要给两个变量 a, b 同时赋值 1,那么干脆这样写既省事又方便:

>>> b = a = 1
>>> a, b
(1, 1)

像这种直接把所有提供的变量名都赋值给右侧对象的形式称之为:多目标赋值语句
当然,这就相当于两个赋值语句:

>>> a = 1
>>> b = a

共享引用

这里只有一个对象,由两个变量共享,这三个变量全都指向内存中的同一个对象(也就是相同的内存空间)。为什么这样说,我们可以看下内存地址的变化:

>>> b = a = 1
>>> id(a)
1831258192
>>> id(b)
1831258192
>>> id(1)
1831258192

这种形式叫做共享引用:同一个对象由两个变量共享,两个变量引用了同一对象
image.png


### 修改指向不可变数据类型的变量值 先修改b的值,让它加1 ```python >>> b = b + 1 >>> a, b (1, 2) >>> id(a) 1831258192 >>> id(b) 1831258224 >>> id(2) 1831258224 ``` 可以看到变量b的自增,又创建了一个新的对象—代表整型值2。类似这种,当值发生变化,引用对象的内存地址也随之而变的成为不可变数据类型。不可变数据类型还有浮点型、字符串和元组 ![image.png](http://testingpai.com/upload/file/2019/15c47802-e386-4d35-a84c-1f1e9597eee5.png)

修改指向可变数据类型的变量值

还是上面的例子,如果我们把变量 a 和变量 b 同时指向字典时,id(a) = id(b)

>>> b = a = {"name":"Jack"}
>>> id(a)
32196424
>>> id(b)
32196424

image.png

当修改 b 的值时,发现 a 的值也发生了变化。因为当给字典内部添加元素后,字典的内存地址不会发生变化,所以对变量 b 的操作不会引起引用对象的地址变化,只相当于同样的一个地址得到了扩充。类似这种,可以在原值上修改,并不会引起引用对象的内存地址改变的,称为可变数据类型。可变数据类型有:列表、字典、集合等

>>> b["age"] = 27
>>> a, b
({'name': 'Jack', 'age': 27}, {'name': 'Jack', 'age':27})
>>> id(a)
32196424
>>> id(b)
32196424
>>>

image.png

多目标赋值语句的注意点

在开始的例子中,类似于"b = a = value",如果想让一个变量值的变化不会引起另一个的变化,请保证 value 是不可变数据类型。反之,如果想同步的改变所有变量的值,则 value 应该是可变数据类型

回帖
请输入回帖内容 ...