import struct class Struct(object): __slots__ = ('__attrs__', '__values__', '__def__', '__size__', '__cooked__') int8 = ('b', 1) uint8 = ('B', 1) int16 = ('h', 2) uint16 = ('H', 2) int32 = ('l', 4) uint32 = ('L', 4) float = ('f', 4) def __init__(self): self.__attrs__ = [] self.__values__ = {} self.__def__ = '' self.__size__ = 0 self.__cooked__ = False def __setattr__(self, name, value): if name in self.__slots__: return object.__setattr__(self, name, value) if self.__cooked__ == False: self.__def__ += value[0] self.__size__ += value[1] self.__attrs__.append(name) self.__values__[name] = 0 else: self.__values__[name] = value def __getattr__(self, name): return self.__values__[name] def __cook__(self): self.__cooked__ = True return self def unpack(self, str): values = struct.unpack(self.__def__, str[:self.__size__]) i = 0 for name in self.__attrs__: self.__values__[name] = values[i] i += 1 return self def pack(self): values = [self.__values__[name] for name in self.__attrs__] return struct.pack(self.__def__, *values) if __name__=='__main__': class TestStruct(Struct): def __init__(self): Struct.__init__(self) self.foo, self.bar = Struct.uint32, Struct.float self.__cook__() test = TestStruct() test.unpack('\xEF\xBE\xAD\xDE\x00\x00\x80\x3F') assert test.foo == 0xDEADBEEF assert test.bar == 1.0 test.foo = 0xCAFEBABE test.bar = 0.0 assert test.pack() == '\xBE\xBA\xFE\xCA\0\0\0\0'