2014-01-10 5 views
0

Я тестирую модуль struct, потому что я хотел бы отправлять простые команды с параметрами в байтах (char) и unsigned int в другое приложение.Python 3 struct.pack() печатать странные символы

Однако я обнаружил некоторые странные вещи при преобразовании в Little Endian неподписанных 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' 

Я был бы признателен любой объяснение или намек. Спасибо заранее!

ответ

6

Питон быть полезным.

Представление bytes будет использовать символы ASCII для любых байтов, которые могут быть распечатываемыми и escape-кодами для остальных.

Таким образом, 0x40 печатается как @, потому что это печатный байт. Но 0x0a представлен как \n, потому что это стандартная escape-последовательность Python для символа новой строки. 0x00 представляется как \x00, шестнадцатеричная управляющая последовательность, обозначающая значение NULL байта. И т. Д.

Все это только представление Python при повторении значений, для вашей выгоды отладки. Само фактическое значение по-прежнему состоит из фактических байтовых значений.

>>> b'\x40' == b'@' 
True 
>>> b'\x0a' == b'\n' 
True 

Это просто, что любые байты в области печати ASCII будут показаны, как этот ASCII символ, а не \xhh шестигранных избежать или выделенный \c один символьных последовательностей.

Если вы хотите, чтобы увидеть только шестнадцатеричные представления, используйте функцию binascii.hexlify():

>>> import binascii 
>>> binascii.hexlify(b'@\x00\x00\x00') 
b'40000000' 
>>> binascii.hexlify(b'\n\x00\x00\x00') 
b'0a000000' 

, которая возвращает байт, шестигранных символов (без префиксов), вместо этого. Возвращаемое значение, конечно, уже не такое же значение, теперь у вас есть bytestring в два раза больше первоначальной длины, состоящей из символов, представляющих шестнадцатеричные значения, буква a до f и 0 до 9 символов.

+0

Блестяще объяснено! Я забыл о персонажах ascii, теперь это имеет смысл – MithPaul

0

"\xNN" это просто способ представления, не prinatble характер ... это даст вам prinable характер, если он может

print "\x0a" == "\n" == chr(10)

Смежные вопросы