Print all fields of ctypes "Structure" with introspection
Question: test.c:

    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct s {
        char a;
        int b;
        float c;
        double d;
    };
    
    struct s *create_struct()
    {
        struct s *res = malloc(sizeof(struct s));
        res->a = 1; res->b = 2; res->c = 3.0f; res->d = 4.0;
        return res;
    }
    

test.py:

    
    
    from ctypes import *
    
    class S(Structure):
        _fields_ = [
            ('a', c_byte),
            ('b', c_int),
            ('c', c_float),
            ('d', c_double)
        ]
    
    lib = CDLL('./test.so')
    
    create_struct = lib.create_struct
    create_struct.restype = POINTER(S)
    create_struct.argtypes = []
    
    s_ptr = create_struct()
    s = s_ptr.contents
    
    print s._fields_[0][0], s.a
    print s._fields_[1][0], s.b
    print s._fields_[2][0], s.c
    print s._fields_[3][0], s.d
    print s.__dict__
    

output:

    
    
    a 1
    b 2
    c 3.0
    d 4.0
    {}
    

I'd like to adapt the python script above to print each field of my s
structure without having to do explicitly for each field. From what I
understand, this can be done using the __dict__ attribute but mine is empty.
Is there any way to do this for a class that extends ctypes.Structure?


Answer: How about using
[`getattr`](http://docs.python.org/2/library/functions.html#getattr)?

    
    
    >>> from ctypes import *
    >>>
    >>> class S(Structure):
    ...     _fields_ = [
    ...         ('a', c_byte),
    ...         ('b', c_int),
    ...         ('c', c_float),
    ...         ('d', c_double)
    ...     ]
    ...
    >>> s = S(1, 2, 3, 4.0)
    >>>
    >>> for field_name, field_type in s._fields_:
    ...     print field_name, getattr(s, field_name)
    ...
    a 1
    b 2
    c 3.0
    d 4.0
    

**UPDATE**

If there is a bitfield in the structure (or union), iterating `_fields_` yield
a tuple of 3 items which will cause `ValueError`. To prevent that you need to
adjust the code:

    
    
    ...
    
    for field in s._fields_:
        print field[0], getattr(s, field[0])
    

