Print all fields of ctypes "Structure" with introspection

How about using 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])

I've just come up with this, for a project I'm working on that has several C structures I want to be able to pretty-print (in a Jupyter notebook, in my case):

>>> # https://stackoverflow.com/a/62011887/76452
>>>
>>> from ctypes import Structure, c_byte, c_int, c_float, c_double
>>>
>>>
>>> class MyStructure(Structure):
...    
...    def __repr__(self) -> str:
...        values = ", ".join(f"{name}={value}"
...                          for name, value in self._asdict().items())
...        return f"<{self.__class__.__name__}: {values}>"
>>>
>>>    def _asdict(self) -> dict:
...        return {field[0]: getattr(self, field[0])
...                for field in self._fields_}
>>> 
>>>
>>> class S(MyStructure):
...     _fields_ = (
...         ('a', c_byte),
...         ('b', c_int),
...         ('c', c_float),
...         ('d', c_double)
...     )
>>>
>>> s = S(1, 2, 3.0, 4.0)
>>> s
<S: a=1, b=2, c=3.0, d=4.0>