斤斤计较且腹黑:彻底理解Python中对象、对象与变量引用的关系
斤斤计较且腹黑:Python对象系列1:可变对象和不可变对象
斤斤计较且腹黑:容器对象与浅拷贝深拷贝的关系
在python中,先生成对象,变量再对对象进行引用,在本例中,1就是对象,然后a再对1进行引用,由于常数是不可变类型,所以1的内存空间是一样的,所以a,b引用的是用一块内存空间。[1]
形象一点来解释就是,先生成一个盒子,盒子里边放着1,然后a,b进行对1引用的时候就是把a,b这两个标签贴到了盒子上。
![3ed3ca2a0e2714728854f464bf726642.png](https://img-blog.csdnimg.cn/img_convert/3ed3ca2a0e2714728854f464bf726642.png)
虽然变量名不一样,但是他们引用的对象是相同的。
append方法进行浅拷贝就相当于python变量赋值一样,在开始的问题中:
a = [1,2]
b = []
b.append(a)
print(b)
a.append(0)
print(b)
b.append(a)就是对a进行了浅拷贝,结果为b=[[1,2]],但b[0]与a引用的对象是相同的,下面通过代码验证一下:
a = [1,2]
b = []
b.append(a)
print(id(a))
print(id(b[0]))
执行结果为:
23768904 23768904
他们的地址是一样的。
![a5c04048ce950b2ad2599f88c7944f76.png](https://img-blog.csdnimg.cn/img_convert/a5c04048ce950b2ad2599f88c7944f76.png)
然后是a.append(0),列表是可变类型,这一步在原地址的列表的末尾添加0,原地址的内容被改变了但是地址没有变,所以a和b[0]的内容同时被改变了,这就是为什么对a进行append操作b会跟着发生改变。
![71f6e97b3c726c45c9a6896e4e5ff94b.png](https://img-blog.csdnimg.cn/img_convert/71f6e97b3c726c45c9a6896e4e5ff94b.png)
发生这些的前提是对同一个地址上的内容进行操作,所以影响了指向该地址的所有变量。如果是进行下面的操作,则是另一种结果:
a = [1,2]
b = []
b.append(a)
print(b)
a = [1,2]
a.append(0)
print(b)
执行结果为:
[[1, 2]] [[1, 2]]
只是多加了一条语句,b就不会随着a的改变而改变,原因就是第二句a=[1,2]重新生成了一个不同的对象(列表是可变类型的),a引用了这个对象,这时候就跟b没有关系了。
![4812538722a019035c88053776c5e2e1.png](https://img-blog.csdnimg.cn/img_convert/4812538722a019035c88053776c5e2e1.png)
参考
- ^对象与变量 https://zhuanlan.zhihu.com/p/161266559