python进阶笔记

  • 一、python中的可变和不可变
  • 二、简单可变类型拷贝
  • 1、Python的深浅拷贝
  • 2、深浅拷贝具体代码实现
  • 三、复杂可变类型拷贝
  • 四、简单不可变类型拷贝
  • 五、复杂不可变类型拷贝
  • 1、不可变类型的深浅拷贝-嵌套类型
  • 六、切片拷贝,字典拷贝
  • 1、切片拷贝
  • 2、字典拷贝
  • 六、import导入模块路径问题
  • 七、import的reload加载问题


一、python中的可变和不可变

目标

能够说出可变和不可变的区别

可变、不可变是指内存中的那块空间是否可以被改变
1、可变类型,创建后可以继续修改对象的内容(值)

字典,列表

2、不可变类型,一旦创建就不可修改的对象(值)

数字,字符串,元组
当内容发生修改,计算机重新分配一块内存空间

二、简单可变类型拷贝

目标

知道简单可变类型深浅拷贝的空间产生情况
为保证数据的独立性,在开发中我们希望两个变量值一样,而且互不影响,这就需要使用到拷贝技术了

1、Python的深浅拷贝

python里的copy模块可以实现拷贝功能

python def 可变餐宿 python 可变与不可变_python def 可变餐宿

拷贝的作用

1、可以减少内存的使用
2、以后在做数据的清洗,修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。

2、深浅拷贝具体代码实现

针对可变类型,深浅拷贝都会产生一个新的空间
copy()浅拷贝,产生新的空间,能够保证数据的独立性

import copy
list1=[1,2,3]
print("list1=",list1,id(list1))
#浅拷贝
list2=copy.copy(list1)
print("list2=",list2,id(list2))
#修改list1
list1.append(5)
print("list1=",list1,id(list1))
print("list2=",list2,id(list2))
结果为:
list1= [1, 2, 3] 2350069862720
list2= [1, 2, 3] 2350069864128
list1= [1, 2, 3, 5] 2350069862720
list2= [1, 2, 3] 2350069864128

总结

list1修改不会改变list2,因为是两个不同的空间

但是list1修改的话,地址不会变,这样就会引起混乱

deepcopy()深拷贝,产生新的空间,能够保证数据的独立性

#深拷贝
list1=[1,2,3]
print("list1=",list1,id(list1))
list2=copy.deepcopy(list1)
print("list2=",list2,id(list2))
#修改list2
list2.append(7)
print("list2=",list2,id(list2))
print("list1=",list1,id(list1))
结果为:
list1= [1, 2, 3] 2533638211392
list2= [1, 2, 3] 2533641050048
list2= [1, 2, 3, 7] 2533641050048
list1= [1, 2, 3] 2533638211392

三、复杂可变类型拷贝

浅拷贝

import copy
A=[1,2,3]
B=[11,22,33]
C=[A,B]
print("A=",A,id(A))
print("B=",B,id(B))
print("C=",C,id(C))
print("C[0]=",C[0],id(C[0]))
#对复杂可变类型进行浅拷贝
#D产生了新的空间
D=copy.copy(C)
print("D=",D,id(D))
print("D[0]=",D[0],id(D[0]))
#修改A的值
A[0]=10
print("D[0]=",D[0],id(D[0]))
结果为:
A= [1, 2, 3] 1802054422656
B= [11, 22, 33] 1802051952448
C= [[1, 2, 3], [11, 22, 33]] 1802054424064
C[0]= [1, 2, 3] 1802054422656
D= [[1, 2, 3], [11, 22, 33]] 1802054542592
D[0]= [1, 2, 3] 1802054422656
D[0]= [10, 2, 3] 1802054422656

总结

浅拷贝只复制最顶层数据

python def 可变餐宿 python 可变与不可变_不可变类_02


深拷贝

#深拷贝
A=[1,2,3]
B=[11,22,33]
C=[A,B]
print("A=",A,id(A))
print("B=",B,id(B))
print("C=",C,id(C))
print("C[0]=",C[0],id(C[0]))
D=copy.deepcopy(C)
print("D=",D,id(D))
print("D[0]=",D[0],id(D[0]))
#修改A的值
A[0] = 10
print("A=", A, id(A))
print("D[0]=", D[0], id(D[0]))
结果为:
A= [1, 2, 3] 2464027445056
B= [11, 22, 33] 2464030281984
C= [[1, 2, 3], [11, 22, 33]] 2464030283456
C[0]= [1, 2, 3] 2464027445056
D= [[1, 2, 3], [11, 22, 33]] 2464030402624
D[0]= [1, 2, 3] 2464030402816
A= [10, 2, 3] 2464027445056
D[0]= [1, 2, 3] 2464030402816

总结

python def 可变餐宿 python 可变与不可变_python def 可变餐宿_03

四、简单不可变类型拷贝

目标

知道简单不可变类型都是浅拷贝

不可变类型,不管是深拷贝还是浅拷贝,都不会开辟新的空间,而是直接引用了被拷贝的数据的地址
浅拷贝

import copy
tuple1=(1,2,3)
print("tuple1=",tuple1,id(tuple1))
tuple2=copy.copy(tuple1)
print("tuple2=",tuple2,id(tuple2))
结果为:
tuple1= (1, 2, 3) 2001449933952
tuple2= (1, 2, 3) 2001449933952

深拷贝

import copy
tuple1=(1,2,3)
print("tuple1=",tuple1,id(tuple1))
tuple2=copy.deepcopy(tuple1)
print("tuple2=",tuple2,id(tuple2))
结果为:
tuple1= (1, 2, 3) 2507813313536
tuple2= (1, 2, 3) 2507813313536

五、复杂不可变类型拷贝

1、不可变类型的深浅拷贝-嵌套类型

浅拷贝

import copy
A=[1,2,3]
B=[11,22,33]
C=(A,B)
print("C=",C,id(C))
D=copy.copy(C)
print("D=",D,id(D))
print("D[0]=",id(D[0]),"C[0]=",id(C[0]),"A=",id(A))
结果为:
C= ([1, 2, 3], [11, 22, 33]) 1572978640768
D= ([1, 2, 3], [11, 22, 33]) 1572978640768
D[0]= 1572981461312 C[0]= 1572981461312 A= 1572981461312

深拷贝

import copy
A=[1,2,3]
B=[11,22,33]
C=(A,B)
print("C=",C,id(C))
D=copy.deepcopy(C)
print("D=",D,id(D))
print("D[0]=",id(D[0]),"C[0]=",id(C[0]),"A=",id(A))
结果为:
C= ([1, 2, 3], [11, 22, 33]) 2603209148288
D= ([1, 2, 3], [11, 22, 33]) 2603211969920
D[0]= 2603212080064 C[0]= 2603211970112 A= 2603211970112

六、切片拷贝,字典拷贝

1、切片拷贝

A=[1,2,3]
B=[11,22,33]
C=(A,B)
print("C=",C,id(C))
D=C[:]
print("D=",D,id(D))
结果为:
C= ([1, 2, 3], [11, 22, 33]) 1814156363648
D= ([1, 2, 3], [11, 22, 33]) 1814156363648

底层为浅拷贝方式

2、字典拷贝

import copy
dict1={"age":[1,2]}
print("dict1=",dict1,id(dict1))
dict2=dict1.copy()
print("dict2=",dict2,id(dict2))
dict1['age'][0]=100
print("dict1=",dict1,id(dict1))
print("dict2=",dict2,id(dict2))
结果为:
dict1= {'age': [1, 2]} 2850238566144
dict2= {'age': [1, 2]} 2850241455552
dict1= {'age': [100, 2]} 2850238566144
dict2= {'age': [100, 2]} 2850241455552

底层为浅拷贝

dict1['age'][0]=100
print("dict1=",dict1,id(dict1))
print("dict2=",dict2,id(dict2))
结果为:
dict1= {'age': [1, 2]} 2850238566144
dict2= {'age': [1, 2]} 2850241455552
dict1= {'age': [100, 2]} 2850238566144
dict2= {'age': [100, 2]} 2850241455552

底层为浅拷贝

六、import导入模块路径问题

目标

知道如何导入指定目录下的模块

存在的问题:

当我们把模块文件放在工程文件的外部,发现无法正常引入模块

原因:

外部的文件夹的路径,没有放到环境变量中

解决方法:

1、导入sys模块
2、sys.path查看环境变量,返回值是列表
3、把自己写的模块的路径加到环境变量中:sys.path.append(path)追加到末尾
sys.path.insert(0,path)追加在第一条

注意:

这不是永久修改,只是临时修改,不过工作上一般都是运行的时候才修改,永久修改会把环境变量搞的乱糟糟

七、import的reload加载问题

目标

能够说出reload的作用

存在的问题:

import导入模块后,如果模块被修改,此时再次import不起作用,import自动防止重复导入,强制重新加载模块,使用reload()函数

解决方案

python def 可变餐宿 python 可变与不可变_深浅拷贝_04