0. 环境
以下适用于Python3.6及以上
$ python
Python 3.6.3 (default, Oct 24 2017, 14:48:20)
[GCC 7.2.0] on linux
1. 编码
关于ASCII、GBK、Unicode等字符集和编码的发展可以参考Python 编码为什么那么蛋疼? - 刘志军的回答 - 知乎,觉得说得挺好的,不过要小心的是回答中的有关代码是Python2的。
而关于字符集和编码的关系,参考字符集与编码,写得挺详细的。还能看看刨根究底学编程。
简单来说,
在Python3中,默认的编码格式是utf-8:
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
那么可以说,在Python3中文本的编码格式(默认)都是utf-8(utf-8是Unicode的一种实现方式)。
2. str和bytes
首先,从Eli Bendersky's website借一副图:
在Python3中,但凡是文本,就一定是str类型,同时,str和bytes都是类。刚学习的时候会弄不清什么是编码什么是类型这里用代码解释一下。
>>> a_str = '中国'
>>> type(a_str)
<class 'str'>
>>> a_str_encode = a_str.encode()
>>> a_str_encode
b'\xe4\xb8\xad\xe5\x9b\xbd'
a_str这个变量,它是str类,也可以说它是str类型的数据,将它按照默认的编码格式去编码后得到a_str_encode,a_str_encode的值是b'\xe4\xb8\xad\xe5\x9b\xbd',开头的b意味着后面跟着的这一串东西是bytes类型的数据,\x代表它和紧接着它的两个数字或者字母共同组成一个16进制数。b'\xe4\xb8\xad\xe5\x9b\xbd'有6个十六进制数,每三个表示一个汉字。而‘\xe4\xb8\xad’就是汉字“中”字的utf-8这种编码的16进制表示。
3. 各种转换
3.1 编码之间的转换
在第二节中,str类型有一个方法是encode,其等同于使用bytes函数显式转换:
>>> a_str_encode
b'\xe4\xb8\xad\xe5\x9b\xbd'
>>> b_str_bytes = bytes(a_str,'utf-8')
>>> b_str_bytes
b'\xe4\xb8\xad\xe5\x9b\xbd'
要说一下ord这个函数,会输出Unicode编码的10进制:
>>> ord('中')
20013
那么如果要把一个utf-8编码的bytes转换成Unicode编码,也就是把中国人能看得懂的汉字转成utf-8之后,想把汉字转成unicode,那么只要先解码(变回去中国人能看懂的)再编码(变成计算机能看懂的):
>>> a_str.encode('utf-8').decode('utf-8').encode('unicode-escape')
b'\\u4e2d\\u56fd'
我在这里的理解是,把编码和解码都当作一种数据库的查询,而Unicode就是这个库,需要编码的时候就是在库里找到这个字对应的十六进制、十进制等等,解码就是相反的操作,但都是遍历字符串中的字符逐个去查询。
至于要将b'\\u4e2d\\u56fd'换成'\\u4e2d\\u56fd'只需要
>>> str(b'\\u4e2d\\u56fd',encoding='utf-8')
'\\u4e2d\\u56fd'
3.2 大端小端以及10进制整数转16进制
我的计算机默认的存储方式是小端:
>>> import sys
>>> sys.byteorder
'little'
对于一个整数10021,将其转成16进制、大端存储的方法有两种(之所以写两种方法是因为后一种可以补位数):
>>> hex(10021)
'0x2725'
>>> e_bytes = (10021).to_bytes(5,byteorder='big')
>>> e_bytes
b"\x00\x00\x00'%"
其中,输出的这串bytes里有'%'和''',其实,用ord函数算出它们的ASCII码并换成16进制:
>>> hex(ord('\''))
'0x27'
>>> hex(ord('%'))
'0x25'
那么最后的结果其实相当于b"\x00\x00\x00\x27\x25"。
>>> import binascii
>>> binascii.hexlify(e_bytes)
b'0000002725'
想直接得到一个10进制数转换成16进制数且是小端存储的方法:
>>> import binascii
>>> binascii.hexlify(b'10021')
b'3130303231'
0条评论