python2.x默认编码方法为ASCII码。字符串赋值时按系统默认编码自动编码,通过decode()方法解码为Unicode,再通过encode()方法编码为指定码。
位(bit)是计算机存储数据的最小单位,每一个位存储一个二进制(0或1)。
字节是计算机计算存储容量的一种计量单位。
字节为数据存储单位,位为数据传输单位。
一个字节(Byte)等于8位(bit)二进制。一个位表示1个二进制的0或1。
计算机的数据以字节的形式存储处理。
字符是各种文字和符号的总称,包括字母、数字、各国文字、标点符号、图形符号、运算符、特殊符号和其他符号。
字符是数据结构中最小的数据存取单位。任何一个文字或符号都是一个字符。
把字符映射到数字的表格,称为编码字符集(Character Set),微软称其为代码页(Code Page),也叫内码。
字符集的每个字符都对应一个唯一的十进制代码值,称为码点(码值)(Code Point),是字符在编码字符集中的编号。
所以编码字符集(Character Set)是所有字符以及对应码点的集合,即编码字符集规定了字符与码点的对应关系。
本文编码字符集简称为字符集。比如,ASCII字符集、GBK字符集、Unicode字符集。
比如,ASCII码字符集中的字符a,对应的码值就是97。
将字符集中字符的十进制代码值转换为实际存储字节系列的映射规则,称为字符编码方式。
比如,ASCII字符编码、GBK字符编码、Unicode字符编码。
NO | 字符集 | 字符编码方式 |
---|---|---|
1 | ASCII字符集 | ASCII字符编码 |
2 | GBK字符集 | GBK字符编码 |
3 | Unicode字符集 | UTF-8字符编码 |
4 | UTF-16字符编码 | |
5 | UTF-32字符编码 |
字符是有不同意义的文字和符号,而计算机只能识别0和1二进制组成的字节,所以要确保字符与字节之间能相互转换,计算机才能存储和处理字符。
字符编码就是把字符转为字节,从字节提取字符的规则。
编码:按照指定字符编码方式找到字符对应的字节。
解码:按照指定字符编码方式找到字节对应的字符。
字符在计算机中存储与读取:
存储:字符->字符集->码值->字符编码方式->二进制->存储。
读取:二进制->字符编码方式->码值->字符集->字符->显示。
标准ASCII码点范围[0,127],只需7位二进制即可覆盖。使用一个字节存储一个字符,首位是0。
GBK中一个中文字符编码成两个字节,一个英文字符编码成一个字节。
计算机解码‘我a你’时,如何区分一次要解析一个字节还是两个字节?
GBK规定,汉字的第一个字节的第1位必须是1。
‘我a你’GBK编码如下:
1xxxxxxx xxxxxxxx|0xxxxxxx|1xxxxxxx xxxxxxxx
计算机解码时,计算机判断第1字节的第1位,如果为1,则为汉字,一次解析2个字节,如果为0,则为ACII字符,一次解析1个字节。前提:字节必须完整,不能部分截取。
Unicode字符集,也叫万国码。
(1) UTF-16编码,每个字符编码为2或4字节。
(2) UTF-32编码,每个字符编码为4字节,1个汉字占2个字节。
(3) UTF-8编码,可变长编码,每个字符编码为1或2或3或4字节,1个汉字占3个字节。
计算机用UTF-8解码时,如何区分要解析1个字节、或2个字节、或3个字节还是4个字节?
(1)第1位为0,则解析1个字节,1个字符占1个字节,
(2)第1位非0,前3位为110,则解析2个字节,舍去前缀110和10,剩余位组成二进制,1个字符占2个字节,
(3)第1位非0,前4位为1110,则解析3个字节,舍去前缀1110、10、10,剩余位组成二进制,1个字符占3个字节,
(4)第1位非0,前5位为11110,则解析4个字节,舍去前缀11110、10、10、10,剩余位组成二进制,1个字符占4个字节,
描述
python通过sys和locale查看解释器和系统编码方式。
示例
>>> import sys
>>> import locale
# python解释器默认编码方式
>>> sys.getdefaultencoding()
'ascii'
# 文件系统编码方式
>>> sys.getfilesystemencoding()
'mbcs'
# 终端输入编码方式
>>> sys.stdin.encoding
'cp936'
# 终端输出编码方式
>>> sys.stdout.encoding
'cp936'
# 当前操作系统编码方式
#当前操作系统的默认语言环境是zh_CN(简体中文),默认字符集是cp936(GBK编码)。
>>> locale.getdefaultlocale()
('zh_CN', 'cp936')
python2.x字符串赋值,c=’梯’为字节串,使用系统默认编码方式进行编码后赋值给c。
python2.x通过u’s’创建unicode文本,为宽字符文本。
描述
python2.x通过s=’xxx’创建的字符串常量为字节串,会自动根据系统默认编码方式进行编码。
示例
>>> import locale;import sys
# locale.getdefaultlocale() 获取系统默认编码方式 为cp936
# sys.getdefaultencoding() 获取py解释器编码方式
>>> locale.getdefaultlocale();sys.getdefaultencoding()
('zh_CN', 'cp936')
'ascii'
>>> c='梯'
# c存放的是字节串,是根据系统默认编码方式编码后的字节串
>>> c
'\xcc\xdd'
# 通过's'.decode('编码方式')进行解码,获取 对应 Unicode 字符
# 解码的编码方式 需与 编码时的系统默认编码方式 cp936 一致
>>> c.decode('cp936')
u'\u68af'
# python2.x通过u's'获得unicode字符
>>> u'梯'
u'\u68af'
描述
python2.x通过u’s’创建unicode文本,为宽字符文本。unicode对象可以进行encode()编码。
NO | 项目 | py2.x | py3.x |
---|---|---|---|
1 | u’s’,unicode常量 | 创建unicode字符串 | 创建str字符串 |
2 | ‘s’,字符串常量 | 创建str字符串,按系统默认编码方式进行编码,类型为str,实际为字节串,可以直接进行decode()解码为unicode。 | 创建str字符串 |
3 | len(‘梯’) | 1个汉字, 按gbk编码时,2个字节,长度2, 按utf-8编码是,3个字节,长度3, 1个字节为2位16进制 | 长度1 |
4 | len(u’梯’) | 长度1 | 长度1 |
示例
# idle py2.7
>>> import sys
>>> sys.version.split(' ')[0]
'2.7.18'
>>> u1,c1=u'梯','梯'
# py2.x u's'创建unicode类型
>>> tuple(map(type,(u1,c1)))
(<type 'unicode'>, <type 'str'>)
# u1-unicode常量,以u开头,用\u转义
# c1-字符串常量,用2位16进制表示1个字节,用\x转义
>>> u1,c1
(u'\u68af', '\xcc\xdd')
>>> tuple(map(len,(u1,c1)))
(1, 2)
# python2.x 字符串常量按系统默认编码方式自动编码
>>> c_gbk='梯'
>>> u=c_gbk.decode('gbk')
>>> c_utf8=u.encode('utf-8')
>>> c_gbk,u,c_utf8
('\xcc\xdd', u'\u68af', '\xe6\xa2\xaf')
# 1个汉字,gbk编码占2个字节,utf-8编码占3个字节,unicode字符集占1个字节
>>> tuple(map(len,(c_gbk,u,c_utf8)))
(2, 1, 3)
# idle py3.7
>>> import sys
>>> sys.version.split(' ')[0]
'3.7.8'
>>> u1,c1=u'梯','梯'
# py3.x u's'创建 str 类型
>>> tuple(map(type,(u1,c1)))
(<class 'str'>, <class 'str'>)
>>> u1,c1
('梯', '梯')
>>> tuple(map(len,(u1,c1)))
(1, 1)
描述
python2.x创建str字符串赋值时,会根据当前系统的默认编码方式自动编码,所以,字符串实际已经是字节串了,此时需要用相同的编码方式进行解码为Unicode,再对Unicode按照指定的编码方式进行encode编码。
python2.x解释器的默认编码方法为ASCII编码,通过sys**.getdefaultencoding()**查看。
字符串赋值使用的编码方式为当前系统的默认编码方式,
通过locale**.getdefaultlocale()**查看。
赋值:自动编码;解码为Unicode,再按指定编码方法编码。
编码:encode(),解码:decode()。
示例
# python2.x 字符串常量按系统默认编码方式自动编码
>>> c_gbk='梯'
# 对字节串按指定编码方法解码为unicode
>>> u=c_gbk.decode('gbk')
# 对unicode按指定编码方法编码,gbk解码后编码为utf-8
>>> c_utf8=u.encode('utf-8')
>>> for x in (c_gbk,u,c_utf8):print x,
梯 梯 梯
# python3.x 字符串赋值后为unicode字符串
>>> c='梯'
>>> c_gbk=c.encode('gbk')
>>> c,c_gbk
('梯', b'\xcc\xdd')
>>> c_utf8=c_gbk.decode('gbk').encode('utf-8')
>>> c,c_gbk,c_utf8
('梯', b'\xcc\xdd', b'\xe6\xa2\xaf')
>>> tuple(map(len,(c,c_gbk,c_utf8)))
(1, 2, 3)
>>> tuple(map(type,(c,c_gbk,c_utf8)))
(<class 'str'>, <class 'bytes'>, <class 'bytes'>)