Допустим, формат файла определен так:
size (uint32)
some_list[size] (uint32)
size_indexes (uint32)
other_list[size_indexes] (uint32)
Итак, есть список some_list
, содержащий некоторые целые числа, а затем есть другой список other_list
, содержащий индексы в some_list
.
Я могу разобрать всю структуру с помощью конструкции следующим образом:
from construct import *
fmt = Struct(
"size" / Int32ul,
"some_list" / Array(this.size, Int32ul),
"size_indexes" / Int32ul,
"other_list" / Array(this.size_indexes, Int32ul),
)
print(fmt.parse(b"\x02\x00\x00\x00\x23\x42\x23\x42\x13\x37\x13\x37\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"))
что дает мне
Container:
size = 2
some_list = ListContainer:
1109606947
924006163
size_indexes = 4
other_list = ListContainer:
1
1
0
1
Теперь, когда я проанализировал формат файла, каков предпочтительный способ создания из него объекта python? Например, вместо того, чтобы other_list содержал индексы, я хотел бы, чтобы он содержал фактические значения.
Не могли бы вы обернуть вокруг него другой объект, обладающий такой способностью, например, такой:
from construct import *
fmt = Struct(
"size" / Int32ul,
"some_list" / Array(this.size, Int32ul),
"size_indexes" / Int32ul,
"other_list" / Array(this.size_indexes, Int32ul),
)
class MyFormat:
def __init__(self, raw):
self._parsed = fmt.parse(raw)
@property
def other_list(self):
for idx in self._parsed.other_list:
yield self._parsed.some_list[idx]
container = MyFormat(b"\x02\x00\x00\x00\x23\x42\x23\x42\x13\x37\x13\x37\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00")
print(list(container.other_list))
который печатает:
[924006163, 924006163, 1109606947, 924006163]
Есть ли лучший, более предпочтительный способ?