Construct - это библиотека для разбора шестнадцатеричных данных. После прочтения данных вы должны сначала определить карту, а затем проанализировать ее. Вы можете найти пример ниже;

....
data, addr = self.s.recvfrom(1024)

c = Struct("sync"/Int16ul, "ID"/Float32l)

x = c.parse(data)

print(x.sync)
print(x.ID)

Моя проблема здесь в том, что я читаю типы данных, для нашего примера Int16ul и Float32l, из списка с именем «varBytes» программно, и их тип «str», как и ожидалось. Имена данных «sync» и «ID» также находятся в списке с именем «varNames». Ниже то, что я пытался;

c = Struct(varNames[0]/varBytes[0],varNames[1]/varBytes[1])

Это не работает. Как я могу решить эту проблему?

0
M.Emin 12 Дек 2018 в 16:21

1 ответ

Лучший ответ

varBytes[0] - это строка, в которой вам нужен объект Int16ul из модуля construct.

Вам нужно превратить строку в объект, который вы можете сделать, получив объект по его имени с getattr, примененным к модулю construct:

varNames[0]/getattr(construct, varBytes[0])

Итак, ваш пример становится:

import construct
from construct import Struct

c = Struct(varNames[0]/getattr(construct, varBytes[0]),
           varNames[1]/getattr(construct, varBytes[1]))

Чтобы построить список аргументов из пары списков, можно применить Struct к списку:

c = Struct(*[varName/getattr(construct, varByte) 
             for varName, varByte in zip(varNames, varBytes)])

Это использует zip, поскольку использование индексов приводит к ошибкам индекса.

1
Dan D. 13 Дек 2018 в 13:12