python对象引用及深浅拷贝

  • python对象引用
  • 深拷贝和浅拷贝


关于python的复制操作及深浅拷贝问题,看了好多帖子,之前还特意写过一篇博客记录当时学习的结论,但当时理解不深,最近有些心得,记录于此。

python对象引用

python中的赋值操作均使用对象引用的方法。所谓对象引用,与其他语言中(比如c#)的引用传递和值传递均不同,介于二者之间。对象引用的具体规则如下:

若a=b,则a和b其实指向同一块内存,内存地址存于a和b内。

规则很简单,但由于python的一些特性,在具体使用中需要注意一些问题:

  1. 当赋值对象b为不可变对象时,比如数字、字符串等,类似于值传递的方法。也就是说,a改变b不会变。
    原因:在python中,不可变对象不能直接在原内存中更新,如果要改变,必须重新开辟内存,这也是不可变对象叫做不可变对象的原因。所以说,当a改变时,a已经指向另一块内存,b却还指向原内存,所以b自然不会随a改变。
  2. 当赋值对象b为可变对象时,比如列表、词典等,类似于引用传递的方法。也就是说,a在原内存发生改变时,b也随之改变;a改变内存地址,指向另一块内存时,b不会随之改变。
    原因:可变对象有两种改变方式。
    第一种:改变内存地址,指向另一块内存。比如a=[0,1]或a=a+[1,2]这种方式。,
    第二种:在原内存中更新内容。比如a+=[1,2]或者a.append(1)这种方式。
    a和b公用一块内存,只有当a在原内存中更新内容时,b才会随之改变。

由于python的对象传递这种特性以及数据类型的复杂性,python中的对象拷贝有两种特别的方式(深拷贝和浅拷贝),从而满足特别的需要。

深拷贝和浅拷贝

深拷贝和浅拷贝的区别是:
指拷贝不彻底,拷贝对象与原对象“藕断丝连”,其中一个改变会导致另一个也改变。
指拷贝的比较彻底,所以拷贝对象改变不会影响原对象。
浅拷贝得到的新对象a和对象b只有第一层不相关。也就是说,a.list1和b.list1仍然是同一块内存地址,如果a.list1更新内存中的内容,b.list1也会随之改变。
而深拷贝则完全拷贝得到了一个全新对象,无论如何改变,都不会影响另一个。