考虑以下代码片段:import sys
for i in range(128, 256):
sys.stdout.write(chr(i))
使用Python2运行此程序,并使用hexdump -C查看结果:
^{pr2}$
等等。不奇怪;从0x80到0xff的128个字节。在
对Python 3执行相同的操作:00000000 c2 80 c2 81 c2 82 c2 83 c2 84 c2 85 c2 86 c2 87 |................|
...
00000070 c2 b8 c2 b9 c2 ba c2 bb c2 bc c2 bd c2 be c2 bf |................|
00000080 c3 80 c3 81 c3 82 c3 83 c3 84 c3 85 c3 86 c3 87 |................|
...
000000f0 c3 b8 c3 b9 c3 ba c3 bb c3 bc c3 bd c3 be c3 bf |................|
总结一下:从0x80到{}的所有内容都有0xc2的前缀。在
从0xc0到{}的所有内容都将第6位设置为零,并在其前面加上0xc3。在
那么,这是怎么回事?在
在python2中,字符串是ASCII,不进行转换。告诉它
写一些超出0-127 ASCII范围的东西,上面写着“好吧!“以及
只写那些字节。简单。在
在python3中,字符串是Unicode。当非ASCII字符
写下来,它们必须以某种方式编码。默认编码是
UTF-8。在
那么,这些值是如何用UTF-8编码的?在
从0x80到{}的代码点编码如下:110vvvvv 10vvvvvv
其中11v字符是代码点的位。在
因此:0x80 hex
1000 0000 8-bit binary
000 1000 0000 11-bit binary
00010 000000 divide into vvvvv vvvvvv
11000010 10000000 resulting UTF-8 octets in binary
0xc2 0x80 resulting UTF-8 octets in hex
0xc0 hex
1100 0000 8-bit binary
000 1100 0000 11-bit binary
00011 000000 divide into vvvvv vvvvvv
11000011 10000000 resulting UTF-8 octets in binary
0xc3 0x80 resulting UTF-8 octets in hex
所以这就是为什么你在87之前得到一个c2。在
在python3中如何避免这些呢?使用bytes类型。在