python直接赋值、浅拷贝和深度拷贝解析

 

直接赋值:其实就是对象的引用(别名)

浅拷贝(copy):拷贝父对象,不会拷贝对象的内部子对象。

深拷贝(deepcopy): copy模块的deepcopy方法,递归完全拷贝了父对象及其子对象。(对于不可变类型做了优化,使其指向同一个地址,因为不可变类型的值发生变化,计算机会重新分配地址空间)

关于直接赋值、不可变类型和可变类型的面试题

  运行以下代码会发生什么变化?为什么?

  

 1 a = [1, 2, 3]
 2 b = a
 3 c = b
 4 a = a + [4, 5, 6]
 5 b += [7, 8, 9]
 6 print(a)
 7 print(b)
 8 print(c)
 9 #[1,2,3,4,5,6]
10 #[1,2,3,7,8,9]
11 #[1,2,3,7,8,9]

解答说明:

a的值赋值给b,b的值赋值给c,  a,b,c指向同一个地址空间,其id值一致

当执行a = a + [4,5,6]时,计算机拿到a地址里面的内容与[4,5,6]做运算的结果为[1,2,3,4,5,6]。计算机分配一个新的地址存储结果,并把结果的名称设置为a。此时打印id(a)时会发现id发生变化

当执行b += [7, 8, 9]时本质上是在执行列表变量的 extend 方法,不会修改变量的引用 。因此id(b), id(c)的值没有发生变化。

 

关于深浅copy的面试题

  运行以下代码会发生什么变化?为什么?

 1 from copy import copy, deepcopy
 2 
 3 a = {'a': 'c', 'b': ['d']}
 4 b = copy(a)
 5 c = deepcopy(a)
 6 a['e'] = 'f'
 7 a['b'].append('g')
 8 print(a)
 9 print(b)
10 print(c)
11 #{'a': 'c', 'b': ['d', 'g'], 'e': 'f'}
12 #{'a': 'c', 'b': ['d', 'g']}
13 #{'a': 'c', 'b': ['d']}

  解答说明:

b是浅copy:拷贝父对象,不会拷贝对象的内部子对象,b的id发生变化,而内部对象的地址没有发生变化,当一些可变类型发生变化,和其指向同一个地址的变量也会发生变化

c是深copy,拷贝父对象, 深拷贝是对于一个对象所有层次的拷贝,对于可变类型的对象会完全拷贝一个到一个新的地址空间。

  

 1 from copy import copy, deepcopy
 2 
 3 a = {'a': 'c', 'b': ['d']}
 4 print(id(a), end='	')
 5 for i in a.values():
 6     print(i, id(i), end='	')
 7 print('
')
 8 
 9 b = copy(a)
10 print(id(b), end='	')
11 for i in b.values():
12     print(i, id(i), end='	')
13 print('
')
14 
15 c = deepcopy(a)
16 print(id(c), end='	')
17 for i in c.values():
18     print(i, id(i), end='	')
19 print('
')
20 a['e'] = 'f'
21 
22 a['b'].append('g')
23 print(a)
24 print(b)
25 print(c)
原文地址:https://www.cnblogs.com/yinyitianya/p/11727432.html