python里我最容易搞不清楚问题之一的encode和decode

因为我自己整理在笔记本上好几次,但是今天看到的时候,又凌乱了。所以还是再次重新整理到博客上。

在计算机的世界里:

1 bytes(字节) == 8 bite(比特);每个bite里存放0或1。

于是一个字节能表示的最大数是:11111111(2) == 255(10);能表示的最小数是:00000000(2) == 0(10)

那么1个字节的范围是:[0, 2^8-1];

同理2个字节的范围是:[0, 2^16-1];以此类推···

电脑(是美国人发明的)最早使用的是ASCII编码准则,里面包含了127个字符,能够对应表示所有的大小写英文字母、数字、特殊符号。因为127<255,所以一个字节对于英文字符的处理是足够的。

但是汉字有几万个,一个字节是完全不够的。至少需要两个字节(2^16-1),并且不与原来的ASCII编码冲突。所以中国制定了GB2312。

中国对应的GB2312;韩国对应的Euc-kr;日本对应的Shift-JIS等等。各国不统一的标准后,就会造成冲突:乱码。

于是统一的标准出现了:Unicode:把所有语言都统一到一套编码里。

Unicode的标准是:通常2个字节表示一个字符,非常生僻字符用4个字节表示。

Unicode解决了乱码冲突问题,同时带来了效率和内存问题:因为Unicode用2个字节表示一个字符,ASCII用1个字节表示。效率和存储上都是一倍的差距。

于是UTF-8编码诞生了:英文字符用1个字节、中文字符用3个字节、生僻字符4至6个字节。如果文本中包含大量英文字符,UTF-8就更节省空间,传输效率也更快。

(ASCII编码属于UTF-8的一部分,所以只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续使用)

字符 ASCII Unicode UTF-8
A 01000001 00000000 01000001 01000001
x 01001110 00101101 11100100 10111000 10101101

python里有2种字符串:

字节码串:没有数据描述的数据

字符串:原始数据+数据描述(指出何种字符集)

python2里:

1.str:字节码串

2.unicode:字符串(定义时需要u''去声明)

因此在python2里,日常字符串的表示为:u'xxx',当前编码设定下的字节码串的表示为:'xxx'。非常不方便,本末倒置。于是在python3里对其修改。

python3里:

1.bytes:字节码串

2.str:字符串(默认支持Unicode字符集,所以不需要u''去定义字符串)

所以在python3里,日常字符串的表示为:'xxx',字节码串的表示为:b'xxx'。

所以现在一般认为python里有两种字符串:

1.存储文本的str:Unicode存储;len(str)是计算字符数

2.存储字节的bytes:原始字节序列ASCII存储;len(bytes)是计算字节数

bytes --decode--> unicode --encode--> bytes

encode()方法:

>>> 'abc'.encode('ascii')  # 按照ascii编码将unicode字符串转换成bytes字节码串
b'abc'
>>> '中文'.encode('utf-8')  # 照ascii编码将unicode字符串转换成bytes字节码串
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')  # 因为ascii编码里没有中文字符,所以报错
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    '中文'.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

decode()方法:

>>> b'abc'.decode('ascii')  # 按照ascii编码将bytes字节码串解码为str字符串
'abc'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')  # 按照utf-8编码将bytes字节码串解码为str字符串
'中文'
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    b'\xe4\xb8\xad\xff'.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')  # 设置错误处理方案为‘ignore’便可忽略\xff的错误
''

写完我自己清楚多啦~ 

猜你喜欢

转载自www.cnblogs.com/hongdanni/p/10484874.html
今日推荐