Emulating C structs in Python
One of the few data types from C that I miss when writing Python code
structs. The simplest replacement is dictionaries, but that means
you have to write
thing['field'] instead of
thing.field. I can't
stand that (it's the extra characters).
If you want
thing.field syntax in Python, you need an object. The
struct emulation is just to use a blank object and
set fields on it:
class MyStruct: pass ms = MyStruct() ms.foo = 10 ms.bar = "abc"
Some people will say that this is an abuse of objects, since they don't have any code, just data. I say to heck with such people; sometimes all I want is data.
(Avoid the temptation to just use '
ms = object()', because it hurts
your ability to tell different types of structs apart via
Initialization this way is tedious, though. We can do it easier and more compactly by using keyword arguments when we create the object, with a little help from the class. Like so:
class Struct: def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) class MyStruct(Struct): pass ms = MyStruct(foo = 10, bar = "abc")
(And look, now our objects have some code.)
It's possible to write the
__init__ function as
self.__dict__.update(kwargs)', but that is fishing a little
too much into the implementation of objects for me. I would rather
use the explicit setattr loop just to be clear about what's going on.
(I am absolutely sure people have been using this idiom for years before I got here.)
Sidebar: dealing with packed binary data
If you need to deal with packed binary data in Python, you want the struct module.
This is a much better tool than C has, because
structs are not good
for this (contrary to what some people think);
structs do not
actually fully specify the memory layout. C compilers are free to
insert padding to make field access more efficient, which makes
struct memory layout machine and compiler dependent.
(I sometimes find it ironic that supposedly 'high level' languages like Python and Perl have better tools to deal with binary structures than 'low level' C.)