python encode、decode、str、unicode、bytes,容易混淆的概念
一、decode和encode
如下这些内容都是针对python3
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码, 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。
如下代码示例:
#coding=utf-8 def code(): s = '中文' print(s) # 中文 str1 = s.encode("gbk") # 将unicode的编码转化成gbk的编码,获得bytes类型对象 print(str1, type(str1)) # b'\xd6\xd0\xce\xc4' <class 'bytes'> str2 = str1.decode('gbk') # 将gbk解码成unicode的字符串,获得字符串类型 print(str2, type(str2)) # 中文 <class 'str'> print(isinstance(str2, str)) # True str3 = s.encode('utf-8') # 将unicode编码成utf-8的字符串,获得bytes类型对象 print(str3, type(str3)) # b'\xe4\xb8\xad\xe6\x96\x87' <class 'bytes'> str4 = str3.decode('utf-8') # 将utf-8解码成unicode的字符串,获得字符串类型 print(str4, type(str4)) # 中文 <class 'str'> if __name__ == '__main__': code()
二、编码
ASCII
编码:它规定1个字节8个比特位代表1个字符的编码,也就是“00000000”这么宽,一个一个字节的解读。例如:01000001表示大写字母A,有时我们会用65这个十进制来表示A在ASCII
中的编码。8个比特位,可以没有重复的最多表示2的8次方(255)个字符。
后来,计算机得到普及,中文、日文、韩文等等国家的文字需要在计算机内表示,ASCII的255位远远不够,于是标准组织制定出了叫做UNICODE的万国码,它规定任何一个字符至少以2个字节表示,可以更多。其中,英文字母就是用2个字节,而汉字是3个字节。这个编码虽然很好,满足了所有人的要求,但是它不兼容ASCII
,同时还占用较多的空间和内存。因为,在计算机世界更多的字符是英文字母,明明可以1个字节就能够表示,非要用2个。
于是UTF-8
编码应运而生,它规定英文字母系列用1个字节表示,汉字用3个字节表示等等。因此,它兼容ASCII
,可以解码早期的文档。UTF-8
很快就得到了广泛的应用。(现在大部分都是utf-8)
在编码的发展历程中,我国还创造了自己的编码方式,例如GBK
,GB2312
,BIG5
。他们只局限于在国内使用,不被国外认可。在GBK
编码中,中文汉字占2个字节。
bytes
是一种比特流,它的存在形式是01010001110这种。 但为了在ide环境中让我们相对直观的观察,它被表现成了b'\xe4\xb8\xad\xe6\x96\x87'
这种形式,开头的b
表示这是一个bytes
类型。
>>> s = '中文' >>> s.encode("utf-8") b'\xe4\xb8\xad\xe6\x96\x87'
为什么英文显示是'hello'呢,因为英文里,utf-8与unicode编码方式是一样的,所以英文显示没有区别,其实也是数字。
>>> s = 'hello中文' >>> s.encode("utf-8") b'hello\xe4\xb8\xad\xe6\x96\x87'
硬盘中一般编码都是uft-8,而在内存中采用unicode编码方式。
python中的str其实显示的就是读取unicode,str的内存格式就是unicode,所以理解为str就是unicode,unicode就是str。
bytes 是 Python 3.x 新增的类型,在 Python 2.x 中是不存在的。
参考:https://blog.csdn.net/lyb3b3b/article/details/74993327