Iterable Ctypes Struct

mark.seagoe at gmail.com mark.seagoe at gmail.com
Wed Feb 11 12:01:19 EST 2009


On Feb 10, 9:52 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Wed, 11 Feb 2009 00:31:26 -0200, <mark.sea... at 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



More information about the Python-list mailing list