1.前言

赋值操作

a = 1  # 内存会为1创建一个数据单元,再让变量a指向这个数据单元
print(id(a))    # 940417552
a = 2  # 内存会为2重新创建一个数据单元,让变量a指向新的数据单元
print(id(a))    # 1940417584

list1 = [1,2,3,4]
print(id(list1))
list1[0] = 11
print(id(list1))

# 创建一个新的变量赋值给原变量;
a = 1
b = 1
c = a 
list1 = [1,2,3]
list2 = lis1
print(id(a),id(b),id(c))
print(id(list1),id(list2))
// 输出结果:内存地址并没有改变,其实这种方式类似于变量别名
1860398096 1860398096 1860398096
2570308110472 2570308110472

2.浅拷贝分析

代码

import copy
a = [1,"2",[3,4]]
b = copy.copy(a)
print(id(a),id(b))    # 内存地址改变说明创建新的对象
print(id(index) for index in a)
print(id(index) for index in b)    # 引用对象中的原始元素
b[0] = "a"
print(a,b)    # 修改不可变对象,会重新创建新的对象,对源对象没有影响
b[2][0] = "A"    
print(a,b)    # 修改可变对象,直接修改元素的值,对原对象会有影响

// 输出结果:
2453878163528 2453879464584
<generator object <genexpr> at 0x0000023B5687EF68>
<generator object <genexpr> at 0x0000023B5687EF68>
[1, '2', [3, 4]] ['a', '2', [3, 4]]
[1, '2', ['A', 4]] ['a', '2', ['A', 4]]

浅拷贝总结

1.浅拷贝会创建新的列表对象,但是对于列表中的元素,浅拷贝使用原始元素的引用(内存地址)
2.改变浅拷贝对象中的元素,如果元素是不可变对象,会创建新的对象(不影响原始元素);如果是可变对象,不会创建新对象,直接进行修改(响应原始元素)

3.深拷贝分析

代码

import copy
a = [1,"2",[3,4]]
b = copy.deepcopy(a)
print(id(a),id(b))     # 内存地址改变说明创建新的对象
print(id(index) for index in a)
print(id(index) for index in b)    # 引用对象中的原始元素;但对于可变对象会创建新的对象
print(id(a[2]),id(b[2]))    # 1599702285704 1599702270344
b[0] = "a"
print(a,b)    # 修改不可变对象,会重新创建新的对象,对源对象没有影响
b[2][0] = "A"    # 修改可变对象,直接修改元素的值,对原对象没有影响
print(a,b)
// 输出结果: 
2535615973448 2535617299080    
<generator object <genexpr> at 0x0000024E5E7C1F10>
<generator object <genexpr> at 0x0000024E5E7C1F10>
[1, '2', [3, 4]] ['a', '2', [3, 4]]
[1, '2', [3, 4]] ['a', '2', ['A', 4]]

深拷贝总结

1.深拷贝会创建的列表对象,对于列表中的元素,如果是不可变对象会引用原始元素,如果是可变对象会创建新的对象
2.改变深拷贝中的元素,如果是不可变对象,会创建新的对象(不影响原始元素),如果是可变对象,不会创建的新的对象,直接进行修改(不会影响原始元素)—— 因为在拷贝阶段对可变对象创建了新的对象

英格拉姆浩
40 声望12 粉丝

面对焦虑,认识自我,提升技术


« 上一篇
Nginx进程模型
下一篇 »
Python三大活器