Ever since I read Dave Beazley’s post on binary I/O handling (http://dabeaz.blogspot.com/2009/08/python-binary-io-handling.html) I’ve wanted to create a Python library for a certain wire protocol. However, I can’t find the best solution for variable length structures. Here’s what I want to do:
import ctypes as c class Point(c.Structure): _fields_ = [ ('x',c.c_double), ('y',c.c_double), ('z',c.c_double) ] class Points(c.Structure): _fields_ = [ ('num_points', c.c_uint32), ('points', Point*num_points) # num_points not yet defined! ]
The class Points
won’t work since num_points
isn’t defined yet. I could redefine the _fields_
variable later once num_points
is known, but since it’s a class variable it would effect all of the other Points
instances.
What is a pythonic solution to this problem?
Advertisement
Answer
The most straightforward way, with the example you gave is to define the structure just when you have the information you need.
A simple way of doing that is creating the class at the point you will use it, not at module root – you can, for example, just put the class
body inside a function, that will act as a factory – I think that is the most readable way.
import ctypes as c class Point(c.Structure): _fields_ = [ ('x',c.c_double), ('y',c.c_double), ('z',c.c_double) ] def points_factory(num_points): class Points(c.Structure): _fields_ = [ ('num_points', c.c_uint32), ('points', Point*num_points) ] return Points #and when you need it in the code: Points = points_factory(5)
Sorry – It is the C code that will “fill in” the values for you – that is not the answer them. WIll post another way.