#python
#python
Вопрос:
У меня есть следующий код (данные — это байтовый объект):
v = sum(struct.unpack('!%sH' % int(len(data)/2), data))
Часть, которая меня смущает, — это %sH в строке формата и % int(len(data)/2
Как именно работает эта часть кода? Какова длина байтового объекта? И из чего именно это складывается?
Ответ №1:
Предполагая, что у вас есть строка байтов data
, такая как:
>>> data = b'x01x02x03x04'
>>> data
'x01x02x03x04'
Длина — это количество байтов (или символов) в байтовой строке:
>>> len(data)
4
Итак, это эквивалентно вашему коду:
>>> import struct
>>> struct.unpack('!2H', data)
(258, 772)
Это указывает struct
модулю использовать следующие символы формата:
!
— использовать сетевой режим (big endian)2H
— распакуйте 2 x неподписанных коротких файла (по 16 бит каждый)
И он возвращает два целых числа, которые соответствуют предоставленным нами данным:
>>> 'x' % 258
'0102'
>>> 'x' % 772
'0304'
Все, что делает ваш код, это автоматически вычисляет количество unsigned shorts
на лету
>>> struct.unpack('!%sH' % int(len(data)/2), data)
(258, 772)
Но в int
преобразовании нет необходимости, и на самом деле не следует использовать %s
заполнитель, поскольку он предназначен для замены строки:
>>> struct.unpack('!%dH' % (len(data)/2), data)
(258, 772)
Таким образом, unpack возвращает два целых числа, относящиеся к распаковке 2 unsigned shorts
из байта данных str. Затем Sum возвращает сумму этих:
>>> sum(struct.unpack('!%dH' % (len(data)/2), data))
1030
Ответ №2:
Как работает ваш код:
- Вы интерпретируете байтовую структуру
data
struct.unpack
использует строку для определения байтового формата данных, которые вы хотите интерпретировать- Заданный формат
stuct.unpack
возвращает итерацию интерпретируемых данных.
- Затем вы суммируете interable.
Форматирование байтов
Чтобы интерпретировать передаваемые вами данные, вы создаете строку, сообщающую Python, в какой форме data
они представлены. В частности, %sH
часть представляет собой сокращенную комбинацию для этого количества беззнаковых сокращений, которые затем вы форматируете, чтобы указать точное количество, которое unsigned short
вы хотите.
В этом случае число равно:
int(len(data) / 2)
потому что unsigned short
обычно имеет ширину 2 байта.