繁体   English   中英

为什么python2和python3的print输出同一个字符串不同?

[英]Why is the output of print in python2 and python3 different with the same string?

在python2中:

$ python2 -c 'print "\x08\x04\x87\x18"' | hexdump -C
00000000  08 04 87 18 0a                                    |.....|
00000005

在python3中:

$ python3 -c 'print("\x08\x04\x87\x18")' | hexdump -C
00000000  08 04 c2 87 18 0a                                 |......|
00000006

为什么这里有字节"\\xc2"

编辑

我认为当字符串具有非 ascii 字符时,python3 会将字节"\\xc2"附加到字符串。 (正如@Ashraful Islam 所说)

那么如何在python3中避免这种情况呢?

考虑以下代码片段:

import sys
for i in range(128, 256):
    sys.stdout.write(chr(i))

使用 Python 2 运行它并使用hexdump -C查看结果:

00000000  80 81 82 83 84 85 86 87  88 89 8a 8b 8c 8d 8e 8f  |................|

等等。 没有惊喜; 0x800xff 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  |................|

总结一下:

  • 一切从0x800xbf已经0xc2前缀。
  • 0xc00xff所有内容都将第 6 位设置为零,并在前面添加了0xc3

那么,这里发生了什么?

在 Python 2 中,字符串是 ASCII 并且不进行转换。 告诉它写一些 0-127 ASCII 范围之外的东西,它说“oky-doke!” 并只写入这些字节。 简单的。

在 Python 3 中,字符串是Unicode 写入非 ASCII 字符时,必须以某种方式对其进行编码 默认编码为 UTF-8。

那么,这些值是如何用 UTF-8 编码的呢?

0x800x7ff代码点编码如下:

110vvvvv 10vvvvvv

其中 11 个v字符是代码点的位。

因此:

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的原因。

如何在 Python 3 中避免这一切? 使用bytes类型。

Python 2 的默认字符串类型是字节字符串。 字节字符串写为"abc"而 Unicode 字符串写为u"abc"

Python 3 的默认字符串类型是 Unicode 字符串。 字节字符串写为b"abc"而 Unicode 字符串写为"abc"u"abc"仍然有效)。 由于有数百万个 Unicode 字符,将它们打印为字节需要一种编码(在您的情况下为UTF-8 ),每个代码点需要多个字节。

首先在 Python 3 中使用字节字符串来获取与 Python 2 相同的类型。 然后,因为 Python 3 的print需要 Unicode 字符串,所以使用sys.stdout.buffer.write写入原始 stdout 接口,它需要字节字符串。

python3 -c 'import sys; sys.stdout.buffer.write(b"\x08\x04\x87\x18")'

请注意,如果写入文件,则存在类似问题。 对于无编码转换,以二进制模式'wb'打开文件并写入字节字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM