From StringIO import StringIO import struct class BinaryIO(StringIO): def writepack(self, fmt, *values): self. Write(struct. Pack('Writepack('I', 42) data.
Writepack('II', 1, 2) return data.getvalue().
You can try to implement some sort of declarative syntax for your data. Which may result in something like: class Image(SomeClassWithMetamagic): type = PackedValue(2) attribute = PackedValue('attributes') # accessed via self. __dict__ #or using decorators @pack(.
The declarative syntax is good if you don't need complex programmatic logic to build the serialization (i.e. Lots of ifs and fors). I have used the declarative approach to specify the serialization, deserialization and automatically generated documentation in one go for a binary fileformat.
– Ants Aasma May 21 '09 at 20:22.
How about protocol buffers google's extensive cross language format and protocol of sharing data.
If you just want nicer syntax, you can abuse generators/decorators: from functools import wraps def packed(g): '''a decorator that packs the list data items that is generated by the decorated function ''' @wraps(g) def wrapper(*p, **kw): data = for params in g(*p, **kw): fmt = params0 fields = params1: data. Append(struct. Pack('Join(data) return wrapper @packed def as_binary(self): '''just |yield|s the data items that should be packed by the decorator ''' yield 'I', 2 yield 'II', self.image.
Size0, self.image. Size1 yield 'I', len(self. Attributes) for attribute in self.
Attributes: yield 'I', attribute. Id yield 'H', attribute. Type if attribute.
Type == 0: yield 'I', attribute. TypeEx Basically this uses the generator to implement a "monad", an abstraction usually found in functional languages like Haskell. It separates the generation of some values from the code that decides how to combine these values together.It's more a functional programming approach then "pythonic", but I think it improves readability.
1. I was literally just seconds away of posting the exact same solution. One small improvement to enhance readability would be to encapsulate the datatype string in a function so yield 'I', attribute.Id becomes yield UInt(attribute.
Id). – Ants Aasma May 21 '09 at 20:17.
Def to_binary(self): struct_i_pack = struct. Struct('Struct('Pack struct_ih_pack = struct. Struct('Struct('Size), struct_i_pack(len(self.
Attributes)), ''. Join( struct_ih_pack(a. Id, a.
Type) if a. Type else struct_ihi_pack(a. Id, a.
Type, a. TypeEx) for a in attributes ) ).
You could refactor your code to wrap boilerplate in a class. Something like: def to_binary(self): 'Return the binary representation as a string. ' binary = BinaryWrapper() # Binary version number.Binary.
Pack('Pack_all(stuff) return binary. Get_packed().
The worst problem is that you need corresponding code in C++ to read the output. Can you reasonably arrange to have both the reading and writing code mechanically derive from or use a common specification? How to go about that depends on your C++ needs as much as Python.
You can get rid of the repetition while still as readable easily like this: def to_binary(self): output = struct. Pack( 'Size1, len(self. Attributes) ) return output + ''.
Join( struct. Pack('Type, attribute. TypeEx) for attribute in self.
Attributes ).
I think you missed "if attribute. Type == 0:" – Darius Bacon May 21 '09 at 21:37.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.