上一篇文章介绍了计算机编码发展历史和编码方式,现在我们聚焦到python语言中,在最新的Python3版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言。例如:
print('我喜欢 computer'.encode('utf-8'))
解释:print函数输出的这句话在python里是使用Unicode编码的(当然它此时也在内存中,因为它现在正被加载着...)
- 打印结果:b'\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2 computer'
看这个输出十分有趣,首先,输出是以b开头的,说明这是一段bytes。有没有想起上篇文章说过的utf-8是向下兼容ASCII码的?
你看输出中的英文computer就被原样输出,而ASCII码不能识别的中文,则用utf-8编码方式来表示,如\xe8,\x88等等。
那Unicode编码方式用得好好的,可以直接混合输出英文和中文等多种语言,换成utf-8输出字符只有英文能让我们看懂,中文变成了难以分辨的十六进制(\xe8\xbf\x99\xe5\x8f\xa5\xe8...),我们为什么还要有utf-8编码方式呢?
想到这个问题说明你已经get到点了。你想,utf-8编码方式的优点是什么?
就是省内存啊
那么,由于Python的字符串类型是str,在内存中以Unicode编码的,一个字符对应若干个字节。
如果要在网络上传输,或者保存到磁盘上,就需要把Unicode编码的str变为以字节为单位的bytes,而通过utf-8编码或者ASCII码编码生成的结果就是以字节为单位的bytes。
这句话这么长无非就重复一个观点:
- python中的str是以Unicode编码的,如果要在网络上传输,或者保存到磁盘上,就得转换为utf-8编码方式。
再举个例子:
print('I love computer'.encode('ascii'))
- 打印结果:b'I love computer'
解释:由于'I love computer'是纯英语,所以可以用ASCII编码。
再看:'I love computer'和'b'I love computer''有什么不同?没错,多了一个b。这个b大有玄妙之处:
'I love computer'是python中的str,是以Unicode方式编码的。
'b'I love computer''也是python中的str,但它是以ASCII码编码的。
同样用utf-8编码打印结果是一样的,(ASCII编码实际上可以被看成是UTF-8编码的一部分)
好了,前面是对纯英文的str进行编码,那对中文的str编码呢?可以对中文的str进行utf-8编码,可以进行ASCII码编码吗?
print('我喜欢 computer'.encode('ascii'))
报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
str_en = 'I love computer'
str_cn = '我喜欢 computer'
bytes_e = b'I love computer'
bytes_c = b'\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2 computer'
#bytes_cm = b'我喜欢 computer' # bytes can only contain ASCII literal characters.# bytes方法进行编码
def bytes_sample():bytes_en_by = bytes(str_en, encoding='utf_8')bytes_cn_by = bytes(str_cn, encoding='utf_8')print('纯英文字符串转换为bytes:',bytes_en_by)print('含中文字符串转换为bytes:',bytes_cn_by)# 编码
def encode_sample():bytes_en = str_en.encode('utf-8')bytes_cn = str_cn.encode('utf-8')bytes_en_as = str_en.encode('ascii')print('utf-8纯英文编码:',bytes_en)print('utf-8含中文编码:',bytes_cn)print('ascii纯英文编码:',bytes_en_as)#str_bytes= str.encode(str_cn) # 默认utf-8,等价于下面3个#str_bytes= str.encode(str_cn,'utf_8')#str_bytes= str.encode(str_cn,encoding='utf_8')str_bytes= str_cn.encode()print('str转成by含中文:',str_bytes)#bytes_cn_as = str_cn.encode('ascii')#print('ascii含中文编码,会报错:',bytes_cn_as)# 解码
def decode_sample():str_e = bytes_e.decode('utf-8')str_c = bytes_c.decode('utf-8')str_a = bytes_e.decode('ascii')print('utf-8纯英文解码:',str_e)print('utf-8含中文解码:',str_c)print('ascii纯英文解码:',str_a)if __name__ == '__main__':encode_sample()#decode_sample()#bytes_sample()
注意:b后面加上字符串,可以自动转换为bytes类型,但是只针对ASCII类型