今日概要
- 深浅拷贝(重点)
- 文件操作
详细内容
-
直接赋值: 直接将对象的引用赋值给另一个对象
v1=1000 v2=v1 #v1 v2指向同一个内存地址 print(id(v1),id(v2))#相等 v1="new_value print(id(v1),id(v2))#不等 v1=[1,2,3] v2=v1 ##v1 v2指向同一个内存地址 v1.append("45") print(v2) #[1,2,3,4,5] ##v1 v2指向同一个内存地址 修改v1内存地址的内容 v2也会跟着改变
解析: 变量中存放的都是引用地址 当创建v1并赋值的时候,会在内存空间开辟一小块内存空间比如(001):001=1000 v1存放该1000内存地址 当v2=v1的时候 将该内存地址又给了v2 ==>v2也指向 001 地址 ==> v2==1000 当v1="新变量时候" 因为 001存放的1000是不可变类型 v1需要另外开辟空间004:存储"new_value" 此时v2还是指向001内存地址
-
浅拷贝: 只拷贝父对象,不会拷贝子对象(只会copy一层)
-
深拷贝:会拷贝到所有嵌套的子对象
-
不可变类型的copy
按理说会另外开辟一块空间存放v2的“alex”值 ,但是由于小数据缓存池原因,使“alex”只会占用一个内存,所以v2和v1地址相等
#1.字符串及其int型的copy v1="alex" import copy v2=copy.copy(v1) print(id(v1),id(v2))#相等 #按理说会另外开辟一块空间存放v2的“alex”值 ,但是由于小数据缓存池原因,使“alex”只会占用一个内存,所以v2和v1地址相等 #2.字符串及其int型deepcopy v3=copy.deepcopy(v1) print(id(v1),id(v2)) #同理 地址相等
-
列表列表,集合,字典的拷贝
#1.赋值 v1=[1,2,3] v2=v1 print(v2 is v1)#True v1.append("a") print(v1,v2) #[1,2,3,"a"]-->v1 #[1,2,3,"a"]-->v2 #2.copy v1=[1,2,3] import copy v3=copy.copy(v1) print(v3 is v1)#False v1.append("abc")#对v1指向的地址进行内部修改 print(v1,v3) #[1,2,3,"abc"]-->v1 #[1,2,3] --->v3 #3.copy import copy v1 = [1,2,3,{"name":'Gao',"numbers":[7,77,88]},4,5] v2 = copy.copy(v1) print(v1 is v2)#False print(v1[0] is v2[0])#True print(v1[3] is v2[3])#True print(v1[3]['name'] is v2[3]['name'])#True print(v1[3]['numbers'] is v2[3]['numbers'])#True print(v1[3]['numbers'][1] is v2[3]['numbers'][1])#True #3.deepcopy v1=[1,2,3] import copy v4=copy.deepcopy(v1) print(v4 is v1)#False v1.append("aaa") print(v1,v4) #[1,2,3,"aaa"] #[1,2,3]
-
(有嵌套)列表,集合,字典的拷贝
v1=[1,2,3,["a","b"]] import copy #1.浅拷贝 v3=copy.copy(v1) print(v3 is v1)#不等 v1.append("GG")#v1添加 print(v1,v3) #[1, 2, 3, ['a', 'b'],'GG'] --->v1 #[1, 2, 3, ['a', 'b']] --->v3 #v1的第一层列表改变后,v3没有改变 v1[3].append("c") print(v1,v3) #[1, 2, 3, ['a', 'b', 'c'], 'GG'] --->v1 # [1, 2, 3, ['a', 'b', 'c']] #v1的第二层列表(子对象改变后) v3也跟着改变 print(v1[3] is v3[3]) #True ===>v1[3] 和v3[3]指向同一个内存地址 ===>浅拷贝只会拷贝到父对象 不会拷贝到子对象 #2.深拷贝 v1=[1,2,3,["a","b"]] import copy v4=copy.deepcopy(v1) print(v4 is v1)#False v1.append("Gao")#v1改变 print(v4) #[1, 2, 3, ['a', 'b']] 没改变 v1[3].append("c") print(v4) #[1, 2, 3, ['a', 'b']] 没改变 print(v1[3] is v4[3])#False ====>深拷贝会拷贝到所有嵌套的子对象 #3. import copy v1 = [1,2,3,{"name":'gao',"numbers":[7,77,88]},4,5] v2 = copy.deepcopy(v1) print(v1 is v2)#False print(v1[0] is v2[0])#True print(v1[3] is v2[3])#False print(v1[3]['name'] is v2[3]['name'])#True print(v1[3]['numbers'] is v2[3]['numbers'])#False print(v1[3]['numbers'][1] is v2[3]['numbers'][1])#True
-
-
特殊: tuple是不可变类型,但是嵌套的元组深拷贝也会有效
v1=(1,2,3,4) v2=copy.copy(v1) print(id(v1),id(v2))#一样 v2=copy.deepcopy(v1) print(id(v1),id(v2))#一样 v1=(1,2,3,4,[1,2,3]) v2=copy.copy(v1) print(id(v1),id(v2))#一样 v2=copy.deepcopy(v1) print(id(v1),id(v2))#不一样
-
练习
v1=[1,2,3] v2=copu.copy(v1) print(v1 ==v2)#一样 print(v1 is v2)#不同 print(v1[0] is v2[0])#一样 v1=[1,2,3,{'k1':'1':'k2':'2'}] v2=copy.deepcopy(v1) print(v1 == v2)#一样 print(v1 is v2)#不同 print(v1[0] is v2[0])#一样 print(v1[3] is v2[3])#不同
文件操作(open/read/write/close)
-
- 关闭
总结
-
深浅拷贝
-
不可变类型
- 深浅拷贝后,内存地址本该不等 ,但是由于 (小数据缓存机制原因), , (内存地址和value值都相等),(元组tuple的深拷贝除外)
-
可变类型
-
浅拷贝(copy):只会拷贝第一层父对象,嵌套的子对象不会被拷贝,即就是如果嵌套的是(列表/集合/字典)只会拷贝到此类对象的引用地址,而不会深入拷贝地址中的存储值
-
深拷贝(deepcopy):会拷贝到所有嵌套的子对象,(拷贝到不可变类型为止)
所以拷贝的和被拷贝对象中的可变类型的内存地址都不相等
-
-
特殊:tuple
- 浅拷贝:内存地址不变
- 深拷贝:会按照深拷贝原理
-
-
文件操作
- 打开文件 :open("文件路径","mode=r/w/a",encoding="utf-8")
- 打开模式 mode
- r
- w:打开文件之前会清空
- a
- r+
- w+
- a+
- seek(2):光标位置向后移动两个字节
- 读写追加都会根据不同的打开文件模式来自动改变光标位置
- 打开模式 mode
- 操作
- 读
- read()
- readline()
- readlines()
- 写:write
- 关闭:close()
- 读
- 练习
- 去换行 strip()
- 打开文件 :open("文件路径","mode=r/w/a",encoding="utf-8")