Python 3 struct.pack() печатает странные символы
Я тестирую модуль struct, потому что я хотел бы посылать простые команды с параметрами в байтах (char) и без знака int в другое приложение.
Тем не менее, я обнаружил некоторые странные вещи при преобразовании в little-endian unsigned int, эти примеры выводят правильное шестнадцатеричное представление:
>>> import struct
>>> struct.pack('<I',7)
b'\x07\x00\x00\x00'
>>> struct.pack('<I',11)
b'\x0b\x00\x00\x00'
>>> struct.pack('<I',16)
b'\x10\x00\x00\x00'
>>> struct.pack('<I',15)
b'\x0f\x00\x00\x00'
но этих примеров явно нет:
>>> struct.pack('<I',10)
b'\n\x00\x00\x00'
>>> struct.pack('<I',32)
b' \x00\x00\x00'
>>> struct.pack('<I',64)
b'@\x00\x00\x00'
Буду признателен за любое объяснение или подсказку. Спасибо заранее!
2 ответа
Python помогает.
bytes
Представление будет использовать символы ASCII для любых байтов, которые можно распечатать, и escape-коды для остальных.
Таким образом, 0x40 печатается как @
потому что это печатный байт. Но 0x0a
представляется как \n
вместо этого, потому что это стандартная escape-последовательность Python для символа новой строки. 0x00 представляется как \x00
шестнадцатеричная escape-последовательность, обозначающая значение байта NULL. И т.п.
Все это только представление Python при отображении значений, для вашей выгоды отладки. Само фактическое значение все еще состоит из фактических байтовых значений.
>>> b'\x40' == b'@'
True
>>> b'\x0a' == b'\n'
True
Просто любой байт в диапазоне ASCII для печати будет отображаться как символ ASCII, а не как \xhh
шестнадцатеричный побег или выделенный \c
escape-последовательность из одного символа
Если вы хотите видеть только шестнадцатеричные представления, используйте binascii.hexlify()
функция:
>>> import binascii
>>> binascii.hexlify(b'@\x00\x00\x00')
b'40000000'
>>> binascii.hexlify(b'\n\x00\x00\x00')
b'0a000000'
который возвращает байты в виде шестнадцатеричных символов (без префиксов). Возвращаемое значение, конечно же, больше не является тем же значением, теперь у вас есть строка байтов в два раза больше оригинальной длины, состоящая из символов, представляющих шестнадцатеричные значения, литерал a
Через f
а также 0
Через 9
персонажи.
"\xNN"
это просто способ представления непечатного символа... он даст вам печатный символ, если сможет
print "\x0a" == "\n" == chr(10)