代码块,小数据池
在Python中id是内存地址, 只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加到内存中,这个空间是有一个唯一标识的,就好比是身份证号,标识这个空间的叫做内存地址,也就是这个数据(对象)的id,可以利用id()去获取这个数据的内存地址:
s = "abc"
print(id(s)) #2690615639712
is 和 ==
==是比较两边数据是否相等,而is是判断两边内存地址是否相等.如果两边内存地址相等,那么实际是指向同一个内存地址.
内存地址相同值肯定相同,值相同地址不一定相同.
代码块
代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。而作为交互方式(在cmd中进入python解释器中)输入的每个命令都是一个代码块。
代码块的缓存机制
前提条件:在同一个代码块内.
机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。文件执行时(同一个代码块)会把两个变量指向同一个对象,满足缓存机制则他们在内存中只存在一个,即:id相同
适用对象:int(float),str,bool。
具体细则:
int(float):任何数字在同一代码块下都会复用。
bool:True和False在字典中会以1,0方式存在,并且复用。
str:几乎所有的字符串都会符合缓存机制,具体规定如下:
1,非乘法得到的字符串都满足代码块的缓存机制:
s1 = '李白@!#*ewq'
s2 = '李白@!#*ewq'
print(s1 is s2) # True
2.乘数为1时,任何字符串满足代码块的缓存机制
3.乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,满足代码块的缓存机制
优点:能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘字典’中取出复用,避免频繁的创建和销毁,提升效率,节约内存。
小数据池
小数据池,不同代码块的缓存机制,也称为小整数缓存机制,或者称为驻留机制
前提条件:在不同代码块
Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。
python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
其实,无论是缓存还是字符串驻留池,都是python做的一个优化,就是将-5~256的整数,和一定规则的字符串,放在一个‘池’(容器,或者字典)中,无论程序中那些变量指向这些范围内的整数或者字符串,那么他直接在这个‘池’中引用,言外之意,就是内存中之创建一个。
适用对象: int(float),str,bool
对象细则:
int:对于整数来说,小数据池的范围是-5~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。
str:
1.字符串的长度为0或者1,默认都采用了驻留机制(小数据池)
2.字符串的长度>1,且只含有大小写字母,数字,下划线时,才会默认驻留。
3.乘数为1时:仅含大小写字母,数字,下划线,默认驻留。含其他字符,长度<=1,默认驻留。含其他字符,长度>1,默认驻留。
4.乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,默认驻留。
5.指定驻留
from sys import intern
a = intern('[email protected]'*20)
b = intern('[email protected]'*20)
print(a is b)
#指定驻留是你可以指定任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字符串。
bool值就是True,False,无论你创建多少个变量指向True,False,那么他在内存中只存在一个。
优点:能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘池’里拿来用,避免频繁的创建和销毁,提升效率,节约内存
如果在同一代码块下,则采用同一代码块下的换缓存机制。
如果是不同代码块,则采用小数据池的驻留机制。
深浅拷贝
深浅copy其实就是完全复制一份,和部分复制一份的意思。
1.赋值运算
l1 = [1,2,3,['barry','alex']]
l2 = l1
l1[0] = 111
print(l1) #[111,2,3,['barry','alex']]
print(l2) #[111,2,3,['barry','alex']]
对于赋值运算来说,两个变量指向的是同一个内存,因此对一个变量的更改另一个变量也会变.
浅拷贝
对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。
浅拷贝只对变量的第一层进行拷贝,因此对一个变量的可变元素改变,另一个变量也会改变.
#同一代码块下:
l1 = [1, '太白', True, (1,2,3), [22, 33]]
l2 = l1.copy()
print(id(l1), id(l2)) # 2713214468360 2713214524680 会在内存中开辟新空间存放copy的列表,因此两个列表 id不一样
print(id(l1[-2]), id(l2[-2])) # 2547618888008 2547618888008 但是列表内容还是沿用之前内容的内存地址
#因此内容的id相同
print(id(l1[-1]),id(l2[-1])) # 2547620322952 2547620322952
# 不同代码块下:
>>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
>>> l2 = l1.copy()
>>> print(id(l1), id(l2))
1477183162120 1477183162696
>>> print(id(l1[-2]), id(l2[-2]))
1477181814032 1477181814032
>>> print(id(l1[-1]), id(l2[-1]))
1477183162504 1477183162504
l1 = [1, 2, 3, 4, ['alex']]
l2 = l1[::] #** 相当于浅拷贝
l1[-1].append(666)
print(l2) # [1, 2, 3, 4, ['alex',666]]
深拷贝
深拷贝:不可变的数据类型元素会指向原内存地址,而可变的数据类型元素会指向一个新建内存地址.
# 同一代码块下
import copy
l1 = [1, 'alex', True, (1,2,3), [22, 33]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2)) # 2788324482440 2788324483016
print(id(l1[0]),id(l2[0])) # 1470562768 1470562768
print(id(l1[-1]),id(l2[-1])) # 2788324482632 2788324482696
print(id(l1[-2]),id(l2[-2])) # 2788323047752 2788323047752
# 不同代码块下
>>> import copy
>>> l1 = [1, '太白', True, (1, 2, 3), [22, 33]]
>>> l2 = copy.deepcopy(l1)
>>> print(id(l1), id(l2))
1477183162824 1477183162632
>>> print(id(0), id(0))
1470562736 1470562736
>>> print(id(-2), id(-2))
1470562672 1470562672
>>> print(id(l1[-1]), id(l2[-1]))
1477183162120 1477183162312
原文地址:https://www.cnblogs.com/banshannongchang/p/11006391.html