Python的编码与解码

Python的编码与解码

文章目录

字节

一个字节(byte)包括八个比特位(bit),每个比特位表示0或1,一个字节从0000 00001111 1112^8=256个数字。一个ACSII编码使用一个字节(最高位作为奇偶校验位),ASCII实际使用七个比特位来表示字符,共可表示2^7=128个字符。

ACSII编码表

Python的编码与解码

Python,调用chrord函数,我们可以看到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-8gbk两种方式来编码,那对应的要从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') 显示有中文

有任何疑问,可以私聊联系我,欢迎各位的指正和建议。


参考文章:

python3编码问题汇总

Python - Encode()、Decode()、Encoding()

上一篇:arcgis api for js 下载(各版本最全面的地址)


下一篇:AES解密控制台中文乱码问题