python之路---字符编码(改进版2)

对于字符出现乱码的场景可以归纳为

1.在硬盘与内存之间存取数据时字符编码不一致(运行python程序的前两个阶段,与文本编辑器无差)

2.pyhon解释器执行python语法时,创建的字符串类型与终端显示的默认字符编码不一致(运行python程序的第三阶段

第一种场景: 数据存取时出现的乱码问题

在Notepad++中以的Shift-jis编码格式保存写有以下两行内容的文本文件

我是谁
フー・アム・アイ

重新打开文件(以ANSI编码格式)

鎴戞槸?
銉曘兗銉汇偄銉犮兓銈偆

出现乱码(原因:存入与读取的编码格式不一致)将ANSI改为Shift-jis读取

我是?
フー・アム・アイ

中文仍然乱码,日文正常(原因中文字符在存入硬盘时就发生错误,gbk与Shift-jis不兼容)

在Pycharm中,实现将您好用gbk格式写入硬盘,以utf-8格式读取,乱码,改为gbk正常显示(这还是存取不一致导致的乱码问题)--->这解释了两个问题:1.pycharm运行python程序前两步和文本编辑器无差,2.读取数据时字符编码要一致

在python2/3解释器实现 --->用命令行读取上面的gbk格式文件,报错,发现python2默认使用的是ASCLL,3为utf-8--->
在文件头:使用#coding:gbk,使解释器使用自身默认字符编码读到文件第一行时,以下内容采取文件头指定的编码格式解码下面内容,即:将硬盘中的gbk形式二进制,使用gbk二进制--->Unicode二进制的映射关系解码

:在pycharm中指定文件头编码格式的作用是,使解释器将文件从硬盘读到到内存的过程使用该模式解码,而当我们用pycharm时,定义头信息时pycharm自动将文件存入硬盘的编码形式转换为文件头指定形式

 第二种场景: python解释器在执行python语法时出现乱码

首先明白python2/python3中两种形式:

python3的str为unicode型 --->通过编码可以获得bytes型
python2的str为bytes型   --->  加u''转换为unicode型

py3执行程序的第三阶段(开始识别语法时),python3为字符串开辟一条空间(这个空间存在于python解释器空间内但不同于存放python程序代码的文本空间)用于存放unicode类型的字符(即在内存中字符串以unicode形式存在)-->这致使无论在win的gbk默认编码,还是python解释器的utf-8/ASCLL都不会报错(unicode与任何格式编码都有对应关系)
而对于python2中开辟空间存放字符串的形式为文件头指定格式(这就可能造乱码问题)--->使用x=u'x'避免乱码

#encoding:gbk 
x = '上'
print(x)
--->��
过程解析解释--->python2在执行python语法时发现x = '上'
这是个创建变量的操作,即先在内存中开辟一个空间用于存放'上',
然后创建一个名称空间用于存放x这个变量名,使x指向存放‘上’的内存地址(绑定)。
这个对象的命名空间含有根据gbk字符编码格式编码的二进制数,
待print()语句执行时,pycharm将'上'这个二进制数根据utf-8(终端默认)的编码映射关系编码成字符(前后不一致,报错)

#encoding:gbk
x = u'上'
print(x)
--->上   --->python通过u将bytes()类型转换为unicode类型

编码转换验证

这个字符在unicode字符编码表对应的是4E0A,而gbk对应的为 494F
而实际为c9cf,为什么?

x = '上'
print(x.encode('gbk'))
b'\xc9\xcf'


gbk是2个bytes表示一个中文字符,1个bytes表示一个英文字符,那么对于中英文连用的二进制,计算机任何区分?
所以采1+7的模式,第八位用于标记,1为中文(继续读8位bit),0位英文字符(只读八位bit),所以
所以c-8=4,

猜你喜欢

转载自blog.csdn.net/ltfdsy/article/details/81218689