Python的编码与解码
文章目录
字节
一个字节(byte)包括八个比特位(bit),每个比特位表示0或1,一个字节从0000 0000
到1111 111
共2^8=256
个数字。一个ACSII编码使用一个字节(最高位作为奇偶校验位),ASCII实际使用七个比特位来表示字符,共可表示2^7=128
个字符。
Python,调用chr
和ord
函数,我们可以看到Python为我们对ASCII编码
进行了转换
>>> chr(65)
'A'
>>> ord('A')
65
>>> ord('a')
97
但是我们知道不同国家的语言是不同的,汉语中的字是一个字一个字,用ACSII编码来表示肯定是不够的,后来出现了Unicode编码
。Unicode编码通常由两个字节组成,共表示256*256个字符。
那原本的ASCII编码中的127个字符只需要在前面补一个全零的字节即可。但是这样会浪费空间和影响传输速度。于是出现了UTF-8编码
。UTF-8编码针对空间浪费问题,因此可长可读。
关于UTF-8编码是如何根据unicode编码来缩短空间的,可以参考一下链接。
https://www.cnblogs.com/shine-lee/p/4504559.html
而中国也有自己的一套标准,那就是GB2312编码
和GBK编码
编码与解码
计算机存储的信息都是二进制,编码和解码就是一种对应关系。
‘A’字符的ASCII值是65,而计算机中存储的是0100 0001。但计算机让我们看到的是’A’。
计算通过使用ASCII解码,发现0100 0001对应的控制字符是’A’,于是就显示出’A’。
编码:让我们看到的直观的字符转换成计算机内的字节形式
解码:把字节形式的字符转换成我们能看懂的,直观的,知道是什么形状的形式
那对应在Python里面,就是 encode 编码
和decode 解码
encode编码和decode解码
encode()
方法为字符串(str)
提供的方法,是用于将str
类型转换成bytes
类型——编码。
str.encode([encoding="utf-8"][,errors="strict"])
# 使用encode方法对原字符串进行编码,不会直接修改原字符串
# 这个函数将字符串转化成相应编码方式的字节形式
# 默认为utf-8方式
>>> str = "中国"
>>> str.encode()
b'\xe4\xb8\xad\xe5\x9b\xbd'
>>> str.encode(encoding='GBK')
b'\xd6\xd0\xb9\xfa'
\xe4\xb8\xad
用二进制表示11100100 10111000 10101101
,也就是说 汉字“中”encode成字节形式是11100100 10111000 10101101
。
decode()
方法和encode
方法相反,用于将bytes
类型的二进制数据转换为str
类型——解码
bytes.decode([encoding="utf-8"][,errors="strict"])
>>> b'\xe4\xb8\xad\xe5\x9b\xbd'.decode()
'中国'
>>> b'\xd6\xd0\xb9\xfa'.decode('GBK')
'中国'
>>> b'\xd6\xd0\xb9\xfa'.decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
在上面,我们用“中国”分别用utf-8
和gbk
两种方式来编码,那对应的要从bytes
的数据解码,方式也不会有错,否则就会报错。
编码转换
- 如何把字符以Unicode的字节形式表现出来?
# xxxx.encode/decode('unicode-escape')
>>> '中国'.encode('unicode-escape')
b'\\u4e2d\\u56fd'
>>> b'\\u4e2d\\u56fd'.decode('unicode-escape')
'中国'
>>> b'\u4e2d\u56fd'.decode('unicode-escape')
'中国'
>>> '\u4e2d\u56fd'
'中国'
b'\\u4e2d\\u56fd'
还是b'\u4e2d\u56fd'
,一个斜杠的缺少好像不影响。'\u4e2d\u56fd'
和b'\u4e2d\u56fd'.decode('unicode-escape')
是相同的。
>>> '\u4e2d\u56fd'.decode('unicode-escape')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
一个‘\uxxxx'
格式的 Unicode字符 可被辨识且被等价于str类型
- 知道一个Unicode字节码,怎么变成UTF-8的字节码呢???
>>> b'\u4e2d\u56fd'.decode('unicode-escape')
'中国' # 解码
>>> b'\u4e2d\u56fd'.decode('unicode-escape').encode()
b'\xe4\xb8\xad\xe5\x9b\xbd' # utf-8编码
>>> chardet.detect(b'\u4e2d\u56fd'.decode('unicode-escape').encode())
{'encoding': 'utf-8', 'confidence': 0.7525, 'language': ''}
补充一点:
我们使用requests库发送请求的时候,有两种方式html = requests.get(url).content.decode("utf-8")
,这里的.content
是读取源文件的字节流,随后将该字节流编码为Unicode编码,方便进行更加精确的解码。也就是使用.content
方法可将Response对象
转换为字节码,结合上面的讲述,对字节形式的字符串进行解码使用decode()函数。
html = requests.get(url).text.encode("utf-8")
,这里的.text
直接读取文件字节流,然后根据encode()函数
进行编码
>>> url = 'https://www.baidu.com/'
>>> html = requests.get(url).text
>>> isinstance(html, bytes)
False
>>> html1 = requests.get(url).content
>>> isinstance(html1, bytes)
True
# html.encode('utf-8') 和 html1显示的内容一样
# html1.decode('utf-8') 显示有中文
有任何疑问,可以私聊联系我,欢迎各位的指正和建议。
参考文章:
Python - Encode()、Decode()、Encoding()