Python赋值/浅/深拷贝

一、可变对象和不可变对象

  • 可变对象,该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。比如列表list字典dict集合set
  • 不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。比如数值类型(int和float)字符串str元组tuple

二、赋值、浅拷贝、深拷贝

1. 赋值

1.1可变对象

a=b=obj 两者在内存中地址一致,并且子元素在内存的地址也一致,所以修改其中一个对象的值,另外一个对象的值肯定也会修改。

1.2 不可变对象

1.2.1 在缓存范围内

只要是某个定值(整型、浮点型、或者字符串),复制给任何对象,所指向的内存地址都是一致的。

1.2.2 不在缓存范围内

某个定值超过缓存范围,比如字符串过长、整型过大,会出现指向该定值的两个对象的内存地址不一致的情况。

2. 浅拷贝

  • 使用copy()函数 from copy import copy
  • 使用切片操作
  • 使用工厂函数(如list/dir/set)

2.1 可变对象

a=copy(b) a和b的内存地址不一致,但是子元素的内存地址都一致。如果b的子元素为不可变对象,那么修改任何一个对象中的该子元素,不会引起另一个对象的该子元素的改变;如果b的子元素为可变对象,那么修改任何一个对象中的该子元素,则会引起另一个对象相应的改变。(其实对子元素的修改就相当于赋值)。

2.2 不可变对象

相当于赋值。

3. 深拷贝

  • from copy import deepcopy

3.1 可变对象

a=deepcopy(b) a和b的内存地址不一致。如果子元素为不可变对象,那么深拷贝后内存地址也不一致,所以修改不会相互影响 ;如果子元素为可变对象,那么深拷贝后内存地址是一致的,但是修改也不会相互影响,具体参考不可变对象的赋值。

3.2 不可变对象

相当于赋值。

三、参考