Python 学习笔记之字符编码
了解:字符编码的起源.
阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII
ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符
ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符),后来为了将拉丁文也编码进了ASCII表,将最高位也占用了
阶段二:为了满足中文和英文,中国人定制了GBK
GBK:2Bytes代表一个中文字符,1Bytes表示一个英文字符
阶段三:各个国家纷纷定制了自己的编码,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr
里各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
阶段四:现阶段
很多地方或老的系统、应用软件仍会采用各种各样的编码,这是历史遗留问题。于是我们必须找出一种解决方案或者说编码方案。
需要同时满足:能够兼容万国字符,与全世界所有的字符编码都有映射关系,可以转换成任意国家的字符编码;
这就是unicode(定长), 统一用2Bytes代表一个字符, 虽然2**16-1=65535,但unicode却可以存放100w+个字符,
因为unicode存放了与其他编码的映射关系,准确地说unicode并不是一种严格意义上的字符编码表,但终于可以同时显示万国语言了。
下载pdf来查看unicode的详情:链接:https://pan.baidu.com/s/1dEV3RYp
那么存储格式的问题来了!
很明显对于通篇都是英文的文本来说,unicode的式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)
于是产生了UTF-8(可变长,全称Unicode Transformation Format),对英文字符只用1Bytes表示,对中文字符用3Bytes,对其他生僻字用更多的Bytes去存
总结:内存中统一采用unicode,浪费空间来换取可以转换成任意编码(不乱码),硬盘可以采用各种编码,如utf-8,保证存放于硬盘或者基于网络传输的数据量很小,提高传输效率与稳定性。

基于目前的现状,内存中的编码固定就是unicode,我们唯一可变的就是硬盘的上对应的字符编码。
此时你可能会觉得,那如果我们以后开发软时统一都用unicode编码,那么不就都统一了吗,关于统一这一点你的思路是没错的,但我们不可会使用unicode编码来编写程序的文件,因为在通篇都是英文的情况下,耗费的空间几乎会多出一倍,这样在软件读入内存或写入磁盘时,都会徒增IO次数,从而降低程序的执行效率。因而我们以后在编写程序的文件时应该统一使用一个更为精准的字符编码utf-8(用1Bytes存英文,3Bytes存中文),再次强调,内存中的编码固定使用unicode。
1、在存入磁盘时,需要将unicode转成一种更为精准的格式,utf-8:全称Unicode Transformation Format,将数据量控制到最精简
2、在读入内存时,需要将utf-8转成unicode
所以我们需要明确:内存中用unicode是为了兼容万国软件,即便是硬盘中有各国编码编写的软件,unicode也有相对应的映射关系,但在现在的开发中,程序员普遍使用utf-8编码了,估计在将来的某一天等所有老的软件都淘汰掉了情况下,就可以变成:内存utf-8<->硬盘utf-8的形式了。
总结:
Unicode:固定在内存中使用,存放了ASCII、GBK、SHIFT_JIS、UTF-8等多国语言编码格式的映射对应关系
UTF-8:可变长的万国字符编码表,用于高效的存储字符文件,用1Bytes存英文,3Bytes存中文,更为精确的存放了各国语言字符的。可以理解为让所有语言可以同时显示在一个文档内的存在

一般文本编辑器的工作流程
第一阶段:打开编辑器
第二阶段:编辑器会载入需要编辑的文本,decode解码--->以unicode读取到内存空间中
第三阶段:编辑器会把刚载入内存空间中的unicode文本数据显示到屏幕上。
例:
GBK字符编码:打开“你好,hello”GBK文件 --读入内存decode---> 内存unicode映射编码 ------> unicode 显示“你好hello”
----修改内容保存内存刷回硬盘encode-->可以存储为utf-8字符编码格式或GBK字符编码格式文件。
utf-8-------->decode---------->unicode----->encode-------->utf-8
python解释器执行文件的流程
第一阶段:启动解释器;
第二阶段:将存储介质上要执行的文件,读入内存decode--->unicode;
第三阶段:decode-->成为unicode后识别Python语法,执行代码。
需要掌握:
内存中固定使用unicode映射关系表应对万国字符编码,但是也要告诉执行程序,文件是以什么格式存储的才能找到对应关系。这就相当于门钥匙,用正确的钥匙才能打开门
# 如果文件test.py以gbk格式保存,内容为:
x = '上'
# 无论是python2执行test.py
# 还是python3执行test.py
# 都会报错(因为python2默认ascii,python3默认utf-8)
# 除非在文件开头指定# coding:gbk
python2的程序字符乱码问题解决:
Python2的特点:读取与打印字符串内容
Python2默认是把文件以ASCII编码格式decode到内存空间里的。
这个特性造成了不必要的麻烦,如果文件是gbk编码格式的就没办法读取到正确的文本数据
这个时候就需要在文件头加上# coding: gbk
# coding:gbk
# 加文件头# coding:gbk 告诉Python文件是以gbk编码格式保存的,所以要以gbk编码格式读入内存。
Python2默认的str类型会把字符串以文件头指定的字符编码格式encode内存里。
文件头指定的是GBK,执行终端是以UTF-8格式来显示字符串的,这个时候打印出来的内容就会出现乱码!
所以在定义字符串的时候要加上小写u ( x =u '上')
# coding:gbk
x =u'上' # 告诉Python不要把字符串encode为文件头格式字符编码,要encode为Unicode格式的。
print(x) # 这个时候打印出来的字符串 utf-8 就能显示 ‘上’了
python3 的程序字符乱码问题解决:
python3的特性:读取与打印字符串内容
python3默认使用UTF-8格式来读取文件decode到内存
所以默认情况下不会出现乱码,但是!!如果程序存储为GBK或其他编码格式,也需要在文件头指定,如例:# coding: gbk
Python3的str字符串类型,默认以Unicode字符编码encode到内存空间,可以不用担心乱码问题了。
如果终端是以其他字符编码格式来呈现字符的,可以使用.encode() 转换字符编码
# coding:gbk
# 特性情况下或这段程序是给老终端运行的,终端只能识别gbk字符编码格式的字符来显示打印内容
x = '上'
print(x.encode('gbk')) # 这个时候打印出来的内容 终端就可以正常显示了。

浙公网安备 33010602011771号