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的整数,和一定规则的字符串,放在某个内存块中,
无论程序中那些变量指向这些范围内的整数或者字符串,那么都直接在这个内存块中引用。


为什么这么做???

  1. 节省内存。
  2. 提高性能与效率。

适用对象: 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

 

posted @   我用python写Bug  阅读(551)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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
点击右上角即可分享
微信分享提示