因为我自己整理在笔记本上好几次,但是今天看到的时候,又凌乱了。所以还是再次重新整理到博客上。
在计算机的世界里:
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'xe4xb8xadxe6x96x87' >>> '中文'.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'xe4xb8xadxe6x96x87'.decode('utf-8') # 按照utf-8编码将bytes字节码串解码为str字符串 '中文' >>> b'xe4xb8xadxff'.decode('utf-8') Traceback (most recent call last): File "<pyshell#15>", line 1, in <module> b'xe4xb8xadxff'.decode('utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte >>> b'xe4xb8xadxff'.decode('utf-8', errors='ignore') # 设置错误处理方案为‘ignore’便可忽略xff的错误 '中'
写完我自己清楚多啦~