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)

Другие вопросы по тегам