On Feb 11, 9:01 am, mark.sea...@gmail.com wrote: > On Feb 10, 9:52 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar> > wrote: > > > > > > > En Wed, 11 Feb 2009 00:31:26 -0200, <mark.sea...@gmail.com> escribió: > > > > I like the ability to access elements of a struct such as with ctypes > > > Structure: > > >>>> myStruct.elementName1 > > > 4 > > > > What I like about it is there are no quotes needed. > > > > What I don't like about it is that it's not iterable: > > >>>> for n in myStruct: <== gives error > > >>>> print n > > > > I don't want to force the end user to have preknowledge of the element > > > names. > > > Note that those names are available as the _fields_ class attribute > > > > Has anyone subclassed ctypes Structure based class to be iterable? > > > Before a noob starts trying to do this, is it possible? How to > > > approach it? > > > The easiest way would be to define __getitem__ accepting index 0, 1, 2... > > until the last defined field. > > Seehttp://docs.python.org/reference/datamodel.html#object.__getitem__ > > > <code> > > from ctypes import Structure > > > class IterableStructure(Structure): > > def __getitem__(self, i): > > if not isinstance(i, int): > > raise TypeError('subindices must be integers: %r' % i) > > return getattr(self, self._fields_[i][0]) > > > </code> > > > This was tested as much as you see here: > > > py> from ctypes import c_int > > py> > > py> class POINT(IterableStructure): > > ... _fields_ = [("x", c_int), > > ... ("y", c_int)] > > ... > > py> point = POINT(10, 20) > > py> print point.x, point.y > > 10 20 > > py> for field in point: > > ... print field > > ... > > 10 > > 20 > > py> print list(point) > > [10, 20] > > > -- > > Gabriel Genellina > > Thanks very much, Gabriel. This is very good start for me. > This works for predefined class. How about a situation where the > fields are added dynamically (as from reading in from an xml file). > For example, if I were to now add another element: > > >>> point.z = 30 > >>> print list(point) > [10, 20] > >>> dir(point) > > ['__class__', '__ctypes_from_outparam__', '__delattr__', '__ > dict__', '__doc__', '__getattribute__', '__getitem__', '__ha > sh__', '__init__', '__module__', '__new__', '__reduce__', '_ > _reduce_ex__', '__repr__', '__setattr__', '__str__', '__weak > ref__', '_b_base_', '_b_needsfree_', '_fields_', '_objects', > 'x', 'y', 'z'] > > I don't know why the iterator (where ever it is) didn't get > incremented. Thanks for any insight. > > Mark- Hide quoted text - > > - Show quoted text -
I tinkered with it and think I have viable solution. I need to append a new member to _fields_ before writing it, then it seems to work. >>> p._fields_.append(('z', c_int)) >>> point.z = 30 >>> print 'List:', list(p) List: [10, 20, 30] Awesome. Thanks! -- http://mail.python.org/mailman/listinfo/python-list