python基础之小数据池、代码块、编码和字节之间换算
一、id is ==
在Python中,id是什么?id是内存地址,== 是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等。
如果内存地址相等,那么这两边其实是指向同一个内存地址。
name = 'shuaige' # 赋值
print('shuaige' == 'shuaige') # True, 数值相同
name2 = 'abc123'
name3 = 'abc123'
print(id(name2), id(name3)) # 2370269674608 2370269674608
print(name2 is name3) # True
在内存中id都是唯一的,如果两个变量指向的值的id相同,就证明他们在内存中是同一个。
is 判断的是两个变量的id值是否相同。
如果is是True, == 一定是True。== 是True,is不一定是True
二、代码块
if True: print(333) print(666) for i in "123456": print(i)
虽然上面的缩进的内容都叫代码块,但是他不是python中严格定义的代码块。
python中真正意义的代码块是什么?
块是一个python程序的文本,他是作为一个单元执行的。
代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。
而对于一个文件中的两个函数,也分别是两个不同的代码块:
def func(): print(333) class A: name = 'xiaojing'
交互模式下,每一行是一个代码块。
什么叫交互方式?就是咱们在cmd中进入Python解释器里面,每一行代码都是一个代码块
>>> i1 = 520 可以理解为这一行在一个文件中。
>>> i2 = 520 可以理解为这一行在另一个文件中。
三、代码块的缓存机制
def test(): x1 = "abcd" x2 = "abcd" print(x1 is x2) test() # True
前提条件:在同一个代码块内。Python3.6及之前的版本(Python3.7之后似乎字符串默认都会缓存)
机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。
通俗来说:python执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在这个代码块中(可以理解为某块地方),
如果再次遇到新的初始化变量命令时,会先在这个代码块中查询是否已经存在这个对象,如果存在,就直接复用这个值(不再重新创建新的对象)。
若不在,则初始化创建,并保存在代码块中。
因此上面的例子,执行时(同一个代码块)会把x1、x2两个变量指向同一个对象,满足缓存机制则他们在内存中只存在一个,即:id相同。
适用对象: int(float), str, bool
对象的具体细则:
- int(float):任何数字在同一代码块下都会复用。
- bool: True和False在字典中会以1,0方式存在,并且复用。
- str:几乎所有的字符串都会符合缓存机制,具体规定如下:
str: 在pycharm中执行(同一个代码块)
1、非乘法得到的字符串都满足代码块的缓存机制: s1 = '你好¥#@#rreq' s2 = '你好¥#@#rreq' print(s1 is s2) # True 2、乘法得到的字符串分两种情况: 2.1 乘数为1时,任何字符串满足代码块的缓存机制: s1 = '你好-*+/@!#¥%……sdf1213' * 1 s2 = '你好-*+/@!#¥%……sdf1213' * 1 print(s1 is s2) # True 2.2 乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,满足代码块的缓存机制: s1 = 'yyds' * 5 s2 = 'yyds' * 5 print(s1 is s2) # True s3 = '_@' * 5 s4 = '_@' * 5 print(s3 is s4) # False 优点:能够提高一些字符串、整数的利用率,避免频繁的创建和销毁,提升效率,节约内存。
四、小数据池(缓存机制,驻留机制)
1、介绍
前提条件:在不同代码块内。
Python默认将-5~256的整数进行了缓存,当变量指向这些整数时,并不会重新创建对象,而是使用已经创建好的缓存对象。
python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
实际上,无论是缓存还是字符串驻留池,都是python做的一个优化,就是将~5-256的整数,和一定规则的字符串,放在某个内存块中,
无论程序中那些变量指向这些范围内的整数或者字符串,那么都直接在这个内存块中引用。
为什么这么做???
- 节省内存。
- 提高性能与效率。
适用对象: int(float), str, bool
2、一定范围内的整数
对于整数来说,小数据池的范围是 -5~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。
3、一定规则的字符串
1,字符串的长度为0或者1,默认都采用了驻留机制(小数据池)
2,字符串的长度>1,且只含有大小写字母,数字,下划线时,才会默认驻留。
3,用乘法得到的字符串,分两种情况。
3.1 乘数为1时
仅含大小写字母,数字,下划线,默认驻留。
含其他字符,长度<=1,默认驻留。
3.2 乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,默认驻留。
4、指定驻留。
from sys import intern a = intern('hello!@'*20) b = intern('hello!@'*20) print(a is b) #指定驻留是你可以指定任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字符串。
五、代码块与小数据池的关系
- 如果在同一代码块下,则采用同一代码块下的换缓存机制。
- 如果是不同代码块,则采用小数据池的驻留机制。
# 在 pycharm 中通过运行文件的方式执行的代码,这是在同一个文件下也就是同一代码块下,采用同一代码块下的缓存机制。 i1 = 520 i2 = 520 print(i1 is i2) # 结果为True 因为代码块下的缓存机制适用于所有数字 # 通过交互方式中执行下面代码,这是不同代码块下,则采用小数据池的驻留机制。 >>> i1 = 520 >>> i2 = 520 >>> print(i1 is i2) False # 不同代码块下的小数据池驻留机制 数字的范围只是-5~256.
六、编码二
""" 位:计算机时间里面的二进制 字节:8位二进制 等于 1个字节 # 这是不变的 字符:就是我们平常可以看到的文字、字母之类的,比如: ABC,我爱python等。 """ ASCII: 只包含字母,数字,特殊字符。 8位二进制(bit)等于1个字节(Bytes),1个字节代表一个字符 A: 0000 0010 B: 0000 0011 unicode: 万国码,包含世界上所有的文字。 创建之初:16位二进制(bit)[即2个字节(Bytes)]代表1个字符 A :0001 0010 0000 0010 中:0011 0010 0000 0110 缺点:还不能完全覆盖世界上的所有文字 升级:32位二进制(bit)[即4个字节(Bytes)]代表1个字符 A :0000 0010 0100 0010 0000 0010 1000 0010 中:0001 0010 0010 0010 0000 0010 0010 0010 缺点:虽然能够覆盖全世界的文字,但是浪费资源。 对unicode升级 --> utf-8:最少用8位表示一个字符。 A :0000 0010 # 字母,数字,特殊字符按照ASCII规则,8位(1个字节)代表1个字符 欧:0000 0010 0100 0010 # 对于欧洲文字,使用16位(2个字节)代表1个字符 中:0000 0010 0001 0010 0000 0010 # 对于中文,使用24位(3个字节)代表1个字符 我国特有的编码 --> GBK(国标):字母,数字,特殊字符,中文。 A :0000 0010 # 字母,数字,特殊字符按照ASCII规则,8位(1个字节)代表1个字符 中:0000 0010 0001 0010 # 对于大部分中文,使用16位(2个字节)代表1个字符 # 国标只包含绝大部分我们日常使用的中文,对于一些比较偏的中文是没有的 1, 编码之间不能互相识别。 2, 网络传输,或者硬盘存储的010101,必须是以非uniocde编码方式的01010101. 3,大环境python3x: str:内存(内部)编码方式为Unicode,因此python3中的字符串不能直接用于网络传输和硬盘存储,为了解决这个问题,就出现了bytes bytes:python的基础数据类型之一,他和str相当于双胞胎,str拥有的所有方法,bytes类型都适用。 区别: 英文字母: str: 表现形式:s1 = 'xiaohei' 内部编码方式:unicode bytes: 表现形式:b1 = b'xiaohei' 内部编码方式:非unicode 中文: str: 表现形式:s1 = '小黑' 内部编码方式:unicode bytes: 表现形式:b1 = b'\xe5\xb0\x8f\xe9\xbb\x91' 内部编码方式:非unicode 如何使用: 你想将一部分内容(字符串)写入文件,或者通过网络socket传输,这样这部分内容(字符串)必须转化成bytes才可以进行。 在平时的代码中,可以直接使用字符串。 具体使用方法:encode编码 decode解码(bytes拥有str的所有方法) encode()不写参数,默认编码成utf-8 str ---> bytes encode 编码 非中文可以使用encode(),也可直接在字符串前加一个 b 表示bytes s1 = 'xiaohei' b1 = b'xiaohei' # 等于 b1 = s1.encode() b2 = b1.upper() print(s1, type(s1)) # xiaohei <class 'str'> print(b1, type(b1)) # b'xiaohei' <class 'bytes'> print(b2, type(b2)) # b'XIAOHEI' <class 'bytes'> 中文只能使用encode() s1 = '小黑' b1 = s1.encode('utf-8') b2 = s1.encode('gbk') print(b1) # b'\xe5\xb0\x8f\xe9\xbb\x91' print(b2) # b'\xd0\xa1\xba\xda' bytes ---> str decode 解码 b1 = b'\xd0\xa1\xba\xda' # gbk的bytes s2 = b1.decode('gbk') # 对应用gbk的解码 print(s2) # 小黑
七、字节单位之间的换算
位(bit,缩写为b)是存储器的最小单位,可以表示一位二进制数。1字节(Byte,缩写为B)由8个位组成,即1Byte=8bit,是存储器的基本单位,通常被作为一个存储单元。通常情况下,把B称为字节、b称为字位、KB称为千字节、MB称为兆字节、GB称为吉字节。
1字位(bit)=1个二进制数
1字节(Byte)=8字位=8个二进制数
1B=8b
1KB=1024B
1MB=1024KB
1GB=1024MB
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix