零散知识点
一:代码块
是一种优化机制,了解直到就可以了,对于实际编码影响不大
如果在cmd终端里面,每一个>>>是一个代码块,这个比较特殊。代码放在pycharm中运行,又有自己的优化,-5-256的优化空间会变得更长,因此没有准确答案,知道有这个优化就可以了,具体是优化到哪个边界无序在意。
每个函数都是一个代码块
类也是一个代码块
代码块缓存机制
同一个代码块重复出现的对象在第一次出现的时候就会缓存下来,方便重复使用
不同代码块缓存有边界,例如-5-256之间的数字会共享内存,str也有缓存规则知道即可,具体是什么不用在意
指定驻留
intern()只能用于str的指定驻留,help(intern)查看
指定任意内容添加到数据池当中,让其在内存中只有一个对象,类似于单例。
from sys import intern a = 'hello!@' b = 'hello!@'#字符串不符合缓存机制,因此开2个对象空间 print("1",a is b)##False a = intern('hello!@'*20)#指定驻留之后 #b = 'hello!@'*20这样做拿到的不是小数据池里面的对象,因为上来解释器看不合符规则,直接就开新内存了
b = intern('hello!@'*20)#这样子做就是指定到小数据池里面看有没有,没有创建,有则直接用。
print("2",a is b)#True
因为只能用于str,因此通用的单例模式不能用intern。因此用到的机会也不多。
二:深浅拷贝
1:只要是拷贝一定会开地址内存,但是没有人关心变量地址内存,只关心数据的内存地址。
深浅拷贝不要用在基本数据类型中,因为都是不可变类型,且大多数都能用缓存机制,因此拷贝他们没有多大的意义。
拷贝多用在比较复杂的对象,例如list set tuple dict 以及定义类型。
首先要知道python都是数据外置,例如列表,它的每个索引位都是4bytes,里面只存放数据的内存地址,这样就可以以不变应万变。
随便数据以及数据类型怎么变,反正列表索引的内存地址是不变的,只要存放的地址你保存好即可。至于地址怎么变的有解释器帮我们完成。
a1=[1,2,3]
a2=copy(a1)#无论是深拷还是浅拷贝,a2和a1的内存地址一定不同
除了基本数据类型,只要是拷贝一定就会开新的内存。
2:分清拷贝和赋值
a=b=100#这是赋值
a=100
b=copy(a)#拷贝,但是从不可变数据类型中看不出来,觉得没有差别。
a=【1,2,3】
b=a#这是赋值
b=copy(a)#此时拷贝,外壳一定拷贝,但是里面的数据就令看,浅拷贝只拷贝外壳,数据是共享的。
3:深浅拷贝的差异在于对内部元素知否进行再拷贝
但是无论是深拷贝还是浅拷贝对于不可变数据类型都不会再拷贝,因为不可变,没有必要再多于的拷贝一份。
只有可变数据类型,且是深拷贝,才会再拷贝一份。
l1=[1,2,3,[1,2,3],(1,2,3)]
对l1进行浅拷贝,只会拷贝最外层的壳,里面所有元素都不会再拷贝
对l1深拷贝,只会拷贝里面的【1,2,3】列表,(1,2,3)不会开内存再拷贝,因为他不可变。1,2,3前3个元素也是不可变的因此也不会拷贝。
from copy import copy from copy import deepcopy l1 = [1,2,3,(12,3,3),[1,2,3]] l2 = l1# 这不是浅拷贝这是变量赋值 print(id(l1)==id(l2)) l3 = copy(l1) print(id(l3)) l1[2]=5 print("l1=",l1) print("l2=",l2) print("l3=",l3) print(id(l1[0])==id(l3[0]))
l1 = [1, 2, 3, 4, ['alex']] l2 = l1[:]#切片是浅拷贝,只要不是明确调用deepcopy()都是浅拷贝 #和l2 = l1.copy()效果是一样的 print(l2) print(id(l1)==id(l2)) print(l1[4] is l2[-1])
结果:
[1, 2, 3, 4, ['alex']]
False
True
[1:]则是拷贝一部分而已。
5:深拷贝
from copy import deepcopy l1 = [1,2,3,(12,3,3),[100]] dd = deepcopy(l1) print(l1) print(l1[0] is dd[0])#int是不可变数据类型所以没有开内存 print(l1[-1] is dd[-1])#因为末尾元素是list类型是可变数据类型所以开了新的数据内存 print(l1[3] is dd[3])
结果:
[1, 2, 3, (12, 3, 3), [100]]
True
False
True
深拷贝只要是不可变类型都会再拷贝一遍外壳。