小数据池 (常量池 -> 字符串缓存) is和==的区别 重新看编码 以及编码之间相互转化

?. 小数据池

在说小数据池之前. 我们先看一个概念念.

什么是代码块: 根据提示我们从官?方?文档找到了这样的说法: A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c‘ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block. A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.

粗略的翻译:

  python程序是由代码块构成的. ?一个代码块的?文本作为python程序执?行行的单元. 代码块: ?个模块, 一个函数, 一个类, 甚?至每?个command命令都是一个代码块. 一个?文件也是一 个代码块, eval()和exec()执?行行的时候也是一个代码块

二. 接下来我们来看?下小数据池

is和==的区别

1. id()

通过id()我们可以查看到?一个变量量表?示的值在内存中的地址.

s = ‘alex‘ print(id(s)) # 4326667072

例如:

id()函数可以帮我们查看一个变量的内存地址
a = 10
b = 30
print(id(a)) # 1515545088
print(id(b)) # 1515545728

使用频率最高的数据类型: 字符串,为了能够快速的创建字符串.
节省内存. 把相同的规律的字符串进行缓存,当下次创建的时候就不在创建了
把字符串的缓存-> 小数据池 -> String iterning -> 常量池 -> 字符串缓存

把字符串的缓存-> 小数据池 -> String iterning -> 常量池 -> 字符串缓存  同样的意思!!!

在创建字符串之前. 先去小数据池对比. 是否已经存在了该字符串.如果存在了.
就不创建新的了. 直接拿原来存在的数据, 省略掉反复重复创建字符串的过程. 节约内存

什么数据会被缓存
数字, 字符串, 布尔值 => 都是不可变的数据类型
1. 数字
a = 1000
b = 1000
print(id(a), id(b)) # 165830000 165830000

如果在py文件中写的字符串. 几乎都是缓存的
在黑窗口里的写的几乎都不会缓存
不同的解释器. 缓存的机制也不一样

优点: 可以帮我们快速的创建对象.节省内存.
缺点: 缓存如果过大. 响应速度会比较慢
不要纠结.

2. is和==

判断左右两端的值是否相等. 是不是?一致.

is 判断左右两端内容的内存地址是否?一致. 如果返回True, 那可以确定这两个变量量使 ?用的是同?一个对象

我们可以这样认为. 如果内存地址相同. 那么值?一定是相等的. 如果值相等. 则不?一定是同?一 个对象

== 比较的是数据, 外貌
is 比较的是内存地址, 比较身份证号

lst1 = [1,2,3]
lst2 = [1,2,3]
# 列表没有小数据池
print(id(lst1), id(lst2)) # 166167560 166126408
print(lst1 == lst2) # True
print(lst1 is lst2) # False

s1 = "我叫周润发"
s2 = "我叫周润发"
print(s1 == s2)
print(s1 is s2) # 小数据池

tu1 = ("周一", "周二")
tu2 = ("周一", "周二")
print(tu1 is tu2) # 地址不相等 False
print(tu1 == tu2) # 内容相等 True

== 比较的是内容
is 比较内存地址

  在python中对-5到256之间的整数会被驻留留在内存中. 将?一定规则的字符串串缓存. 在使?用 的时候, 内存中只会创建?一个该数据的对象. 保存在?小数据池中. 当使?用的时候直接从?小数据 池中获取对象的内存引?用. ?而不需要创建?一个新的数据. 这样会节省更更多的内存区域.

  优点: 能够提?高?一些字符串串, 整数的处理理速度. 省略略的创建对象的过程.

  缺点: 在‘池‘中创建或者插入新的内容会花费更更多的时间.

  对于数字: -5~256是会被加到?小数据池中的. 每次使?用都是同?一个对象. 对于字符串串:

  1. 如果字符串串的?长度是0或者1, 都会默认进?行行缓存

  2. 字符串串?长度?大于1, 但是字符串串中只包含字?母, 数字, 下划线时才会缓存

  3. ?用乘法的到的字符串串. ①. 乘数为1, 仅包含数字, 字?母, 下划线时会被缓存. 如果 包含其他字符, ?而?长度<=1 也会被驻存, ②. 乘数?大于1 . 仅包含数字, 字?母, 下划 线这个时候会被缓存. 但字符串串?长度不能?大于20 4. 指定驻留留. 我们可以通过sys模块中的intern()函数来指定要驻留留的内容.

  OK. 到?目前为?止. 我们已经了了解了了python的?小数据池的?一些基本情况了了. 但是!!!! 还有最后?一 个问题. ?小数据池和最开始的代码块有什什么关系呢? 同样的?一段代码在命令?行行窗?口和在py?文件中. 出现的效果是完全不?一样的.

  在代码块内的缓存机制是不?一样的. 在执?行行同?一个代码块的初始化对象的命令时, 会检 查是否其值是否已经存在, 如果存在, 会将其重?用. 换句句话说: 执?行行同?一个代码块时, 遇到初始 化对象的命令时,他会将初始化的这个变量量与值存储在?一个字典中, 在遇到新的变量量时, 会先 在字典中查询记录, 如果有同样的记录那么它会重复使?用这个字典中的之前的这个值. 所以在 你给出的例例?子中, ?文件执?行行时(同?一个代码块) 会把a, b两个变量量指向同?一个对象.

   如果是不同的代码块, 他就会看这个两个变量量是否是满?足?小数据池的数据, 如果是满?足 ?小数据池的数据则会指向同?一个地址. 所以: a, b的赋值语句句分别被当作两个代码块执?, 但 是他们不满足?数据池的数据所以会得到两个不同的对象, 因?而is判断返回False.

三. 编码的补充

1. python2中默认使?用的是ASCII码. 所以不?支持中?文. 如果需要在Python2中更更改编码. 需要在?文件的开始编写:

# -*- encoding:utf-8 -*

2. python3中: 内存中使?用的是unicode码. 编码回顾:

1. ASCII : 最早的编码. ?里里?面有英?文?大写字?母, ?小写字?母, 数字, ?一些特殊字符.

没有中?文, 8个01代码, 8个bit, 1个byte

2. GBK: 中?文国标码, ?里里?面包含了了ASCII编码和中?文常?用编码.

16个bit, 2个byte

3. UNICODE: 万国码, ?里里?面包含了了全世界所有国家?文字的编码.

32个bit, 4个byte, 包含了了 ASCII

4. UTF-8: 可变?长度的万国码. 是unicode的?一种实现. 最?小字符占8位

1.英?文: 8bit 1byte 2.欧洲?文字:16bit 2byte 3.中?文:24bit 3byte

综上, 除了了ASCII码以外, 其他信息不能直接转换. 在python3的内存中. 在程序运?行行阶段. 使?用的是unicode编码. 因为unicode是万国码. 什什么内 容都可以进?行行显?示. 那么在数据传输和存储的时候由于unicode比较浪费空间和资源. 需要把 unicode转存成UTF-8或者GBK进?行行存储. 怎么转换呢. 在python中可以把?文字信息进?行行编码. 编码之后的内容就可以进?行行传输了了. 编码之后的数据是bytes类型的数据.其实啊. 还是原来的 数据只是经过编码之后表现形式发?生了了改变?而已.

bytes的表现形式:

1. 英?文 b‘alex‘ 英?文的表现形式和字符串串没什什么两样

2. 中?文 b‘\xe4\xb8\xad‘ 这是?一个汉字的UTF-8的bytes表现形式

  记住: 英?文编码之后的结果和源字符串串?一致. 中?文编码之后的结果根据编码的不同. 编码结果 也不同. 我们能看到. ?一个中?文的UTF-8编码是3个字节. ?一个GBK的中?文编码是2个字节. 编码之后的类型就是bytes类型. 在?网络传输和存储的时候我们python是保存和存储的bytes 类型. 那么在对?方接收的时候. 也是接收的bytes类型的数据. 我们可以使?用decode()来进?行行解 码操作. 把bytes类型的数据还原回我们熟悉的字符串:

s = "我今天非常的困" # 21个utf-8
bs = s.encode("gbk") # 把字符串转化成utf-8格式bytes
# bytes不是给人看的. 给机器用的
# 14个字节 gbk
# b‘\xce\xd2\xbd\xf1\xcc\xec\xb7\xc7\xb3\xa3\xb5\xc4\xc0\xa7‘
# 21个字节 utf-8
# b‘\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0‘
print(bs)

utf-8和gbk是不能直接转换的, 必须使用unicode来转换

bs = b‘\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0‘
# 把字节转化回字符串
s = bs.decode("utf-8")
print(s)

b‘\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0‘
把这个bytes转化成gbk的bytes
bs = b‘\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0‘
# 解码
s = bs.decode("utf-8")
print(s)

# 编码
bss = s.encode("gbk")
print(bss)

关于bytes, 非ascii中的内容. 展示的时候都是\x.. 如果是ascii中的内容. 原样输出
name = "alex昨天吃多了"
bs = name.encode("gbk") # b‘alex\xd7\xf2\xcc\xec\xb3\xd4\xb6\xe0\xc1\xcb‘
print(bs)

bss = name.encode("utf-8") # b‘alex\xe6\x98\xa8\xe5\xa4\xa9\xe5\x90\x83\xe5\xa4\x9a\xe4\xba\x86‘
print(bss)

原文地址:https://www.cnblogs.com/H1050676808/p/10061352.html

时间: 2024-08-12 06:44:28

小数据池 (常量池 -> 字符串缓存) is和==的区别 重新看编码 以及编码之间相互转化的相关文章

第七天-数据池/常量池 编码补充

小数据池/常量池(坑,别纠结) : 小数据池 一种数据缓存机制.也被称为驻留机制 用缓存的前提: 数据可以被共享.不可变数据类型 作用/意义:把数据存在小数据池 快速创建对象 共享 节省内存 解释字符串赋值问题等 python中只针对:整数,字符串串,布尔值    注意共享的是不可改变的数据类型 id()  is  == 1 # id() 查看一个变量表示的值的内存地址 2 a = 1000 3 b = 1000 4 c = "lijie" 5 print(id(a)) # 26026

JVM内存结构和常量池

1.虚拟机的构成 虚拟结主要由运行时数据区.执行引擎.类加载器三者构成,我们所说的JVM内存模型指的就是运行时数据区. 2.运行时数据区组成和各个区域的作用 运行时数据区可以分为线程共享和线程不共享两部分,其中堆内存和方法区线程共享,本地方法栈.虚拟机栈.程序计数器线程不共享. 2.1.程序计数器 程序计数器(Program Counter Register),也有称作为PC寄存器.想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当

Java虚拟机原理图解-- 1.2、class文件中的常量池

了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的.感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助. 上一章节&l

《Java虚拟机原理图解》 2、class文件中的常量池

了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的.感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助. 上一章节&l

(十三)class文件结构:常量池(转)

Class类文件的结构 全局规范 1.任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成).本章中,只是通俗地将任意一个有效的类或接口所应当满足的格式称为"Class文件格式",实际上它并不一定以磁盘文件的形式存在."Class文件"应当是一串二进制的字节流,无论以何种形式存在. 2.Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Cl

Jvm(35),class文件结构----常量池

Class文件格式 常量池 先了解常量池中需要存放哪些内容,再讨论用什么类来存放这些内容. 常量池中存放的内容 Class文件中包含常量池,那么我就需要知道常量池会包含哪些内容,接下来才是关心class格式文件用什么类型来存放这些内容. 字面量(Literal) 字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为 final的常量值等. 符号引用(Symbolic References)符号引用则属于编译原理方面的概念,包括了下面三类常量: 类和接口的全限定名(Fully Qual

String、常量池以及intert方法

.class文件常量池 常量池主要存放两类常量:字面量和符号引用. 字面量指文本字符串等. 符号引用指: 类和接口的全限定名 字段的名称和描述符 方法的名称和描述符 编译期结束,当类加载器加载类时,.class文件常量被加入运行常量池,如果常量已存在则不再加载. .class文件常量对象(如String)被创建是预定好的,除非已常量已存在则不再加载. String intern方法 String str1 = new String("Hello"); String str2 = new

pyhon学习第六天 代码块,小数据池(缓存机制,驻留机制),is == id =,字符编码

1.代码块 能够实现某项功能的:模块,函数,类,文件 ##在python的交互模式下,一行代码就是一个代码块分别储存在不同文件中 2. id is ==和= =是赋值 ==比较两边数据内容是否相等 is 比较内存地址是否一致(内存里的id都是唯一的) id() 查看数据的id地址 3.小数据池(缓存机制,驻留机制): 小数据池是python对内存做的一个优化 优化内容:python将-5到256的整数.以及一定规律的字符串提前在内存找那个创建了固定的储存空间 适用小数据池的数据类型:*****

Python 小数据池、代码块以及代码块缓存机制

按照惯例,吟诗一首:苏轼<江城子·乙卯正月二十日夜记梦> 十年生死两茫茫,不思量,自难忘.千里孤坟,无处话凄凉. 纵使相逢应不识,尘满面,鬓如霜. 夜来幽梦忽还乡,小轩窗,正梳妆.相顾无言,惟有泪千行. 料得年年肠断处,明月夜,短松冈. 1. is 和 == 之间的区别 在讲解代码块及其缓存机制之前有必要搞清楚is和==之间的区别 开门见山直接说:==是比较两边变量的值是否相同,is是比较两边变量的内存地址是否相同,在python中内存地址如何获取,当然是使用id(item)函数获取了 举两个