1、什么是字符编码
【ASCII编码由来】计算机只能处理数字(采用8个比特(bit)作为一个字节(byte)),如果处理文本必须把文本转换为数字。美国人最早在设计计算机时,把大小写英文字母、数字和一些符号等127个字符编码到计算机中,也就时ASCII编码(字母大A的编码为65,字母小z的编码为122)。
【GB2312&Unicode编码由来】但是中文至少需要2个字节,且为了不和ASCII编码冲突,中国定制了GB2312编码,把中文编进去。如何解决全世界多种语言的编码问题了,这时就有了Unicode编码。
【UTF-8编码由来】Unicode编码通常为2个字节,ASCII编码为1个字节,前者比后者要多一倍的存储空间,在存储和传输上不划算。因此,把Unicode编码转化为“可变长编码”的UTF-8编码,UTF-8把一个Unicode字符根据其数据大小编码成1到6个字节。如要传输大量包含英文字母的文本,用UTF-8编码可节省空间。
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
2、不同字符编码如何进行转化
1) 对于单个字符,用ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符。
>>> ord('z')
122
>>> chr(65)
'A'
2) bytes类型,用带b前缀的单引号或双引号表示,如:b'ABC';‘ABC’和b'ABC'前者为str,后者为字符,显示虽相同,但bytes的每个字符都只占用一个字节。字符串类型str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,需要把str变为以字节为单位的bytes。
以Unicode表示的str通过encode()方法可以编码为指定的bytes
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last): File "", line 1, inUnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
纯英文str可用ASCII编码为bytes,内容是一样的,含有中文str可用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
在bytes中,无法显示为ASCII字符的字节,用\x##显示。
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
3)如果bytes中包含无法解码的字节,就会报错,如果只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
4)len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
得到字符长度
>>> len('ABC')
3
>>> len('中文')
2
得到字节大小
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6