[英]Python2 and Python3 DPKT appears to return different output formats
[英]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 |................|
等等。 沒有驚喜; 從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
至0xbf
已經0xc2
前綴。0xc0
到0xff
所有內容都將第 6 位設置為零,並在前面添加了0xc3
。那么,這里發生了什么?
在 Python 2 中,字符串是 ASCII 並且不進行轉換。 告訴它寫一些 0-127 ASCII 范圍之外的東西,它說“oky-doke!” 並只寫入這些字節。 簡單的。
在 Python 3 中,字符串是Unicode 。 寫入非 ASCII 字符時,必須以某種方式對其進行編碼。 默認編碼為 UTF-8。
那么,這些值是如何用 UTF-8 編碼的呢?
從0x80
到0x7ff
代碼點編碼如下:
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.