Take a look at the ctypes tutorial. You use the ctypes.Union class:

class test(ctypes.Structure):
    # ...
class test2(ctypes.Structure):
    # ...

class tests(ctypes.Union):
    _fields_ = [("a", test),
                ("b", test2)]
Answer from Adam Rosenfield on Stack Overflow
🌐
Python
docs.python.org › 2.5 › lib › ctypes-structures-unions.html
14.14.1.10 Structures and unions
December 23, 2008 - The field type must be a ctypes type like c_int, or any other derived ctypes type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor: >>> from ctypes import * ...
Discussions

python - Confusion in implementing union using ctypes - Stack Overflow
I am trying to write a code of union using ctypes, but it is not giving desired output... More on stackoverflow.com
🌐 stackoverflow.com
python - Python3: ImportError: No module named '_ctypes' when using Value from module multiprocessing - Stack Overflow
Traceback (most recent call last): ... module> import ctypes File "/usr/local/lib/python3.4/ctypes/__init__.py", line 7, in from _ctypes import Union, Structure, Array ImportError: No module named '_ctypes'... More on stackoverflow.com
🌐 stackoverflow.com
Equivalent of a C union in Python? - Stack Overflow
I figured there was something in ctypes for an exact translation. 2017-07-29T01:38:14.56Z+00:00 ... Save this answer. ... Show activity on this post. Here is what you would do. First, let's create the raw bytes we need, I'll cheat and use numpy: >>> import numpy as np >>> arr = np.array((8,4,... More on stackoverflow.com
🌐 stackoverflow.com
Python ctype Structure/Union Issue - Stack Overflow
So I am trying to do a bitmap. The data comes from a device as a 32bit number and each bit means something. So I was playing around with ctype Structures and Unions. Trying to do the classic int in... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Cdotson
cdotson.com › 2015 › 05 › c-style-unions-and-python
C-Style Unions And Python – Chad Dotson
Using ctypes, you can approach a functionality similar C. Take the following code for example. from ctypes import c_int, c_uint, c_float, Union from struct import unpack class MyType(Union): _fields_ = [("i", c_int), ("u", c_uint), ("f", c_float)] var = MyType() var.i = unpack("i", byte_buffer)[0] ...
🌐
Python
docs.python.org › 3 › library › ctypes.html
ctypes — A foreign function library for Python
Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor: >>> from ctypes import * ...
🌐
Rose-Hulman Institute of Technology
rose-hulman.edu › Class › csse › archive › csse120-old › csse120-old-terms › 201110robotics › Resources › python-3.1.2-docs-html › _sources › library › ctypes.txt
ctypes.txt
:attr:`_fields_` must be a list ... named *x* and *y*, and also shows how to initialize a structure in the constructor:: >>> from ctypes import * >>> class POINT(Structure): ......
🌐
Readthedocs
rawkit.readthedocs.io › en › latest › _modules › ctypes.html
ctypes — rawkit 0.6.0 documentation
"""create and manipulate C data types in Python""" import os as _os, sys as _sys __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name in ("nt", "ce"): from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › help - importerror: no module named '_ctypes'
r/learnpython on Reddit: Help - ImportError: No module named '_ctypes'
August 3, 2022 - Traceback (most recent call last): ... < module> import ctypes File "/usr/local/lib/python3.4/ctypes/init.py", line 7, in <module> from _ctypes import Union, Structure, Array ImportError: No module named '_ctypes'...
🌐
Python
svn.python.org › projects › ctypes › trunk › ctypes › docs › manual › tutorial.html
ctypes tutorial
The field type must be a ctypes type like c_int, or any other derived ctypes type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor: >>> from ctypes import * ...
🌐
University of New Brunswick
cs.unb.ca › ~bremner › teaching › cs2613 › books › python3-doc › library › ctypes.html
ctypes — A foreign function library for Python — Python 3.9.2 documentation
The field type must be a ctypes type like c_int, or any other derived ctypes type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor: >>> from ctypes import * ...
Top answer
1 of 4
13

What about ctypes?

from ctypes import (
        Union, Array, 
        c_uint8, c_uint32, 
        cdll, CDLL
) 

class uint8_array(Array):
    _type_ = c_uint8
    _length_ = 4

class u_type(Union):
    _fields_ = ("data", c_uint32), ("chunk", uint8_array)

# load printf function from Dynamic Linked Libary libc.so.6 (I'm using linux)
libc = CDLL(cdll.LoadLibrary('libc.so.6')._name)
printf = libc.printf

if __name__ == "__main__":
    # initialize union
    _32bitsdata = u_type()
    # set values to chunk
    _32bitsdata.chunk[:] = (1, 2, 3, 4)
    # and print it
    printf(b"Data in 32 bits: %d\n", _32bitsdata.data)
2 of 4
2

Here is what you would do. First, let's create the raw bytes we need, I'll cheat and use numpy:

>>> import numpy as np
>>> arr = np.array((8,4,2,4,8), dtype=np.uint32)
>>> arr
array([8, 4, 2, 4, 8], dtype=uint32)
>>> raw_bytes = arr.tobytes()
>>> raw_bytes
b'\x08\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00'

These could have easily been read from a file. Now, using the struct module is trivial. We use the unsigned int format character 'I':

>>> import struct
>>> list(struct.iter_unpack('I', raw_bytes))
[(8,), (4,), (2,), (4,), (8,)]

Note, each time we iterate we get back a tuple, since our struct has one member, it is a list of singleton tuples. But this is trivial to get into a flat python list:

>>> [t[0] for t in struct.iter_unpack('I', raw_bytes)]
[8, 4, 2, 4, 8]

Another alternative is to read them into an array.array:

>>> import array
>>> my_array = array.array('I', raw_bytes)
>>> my_array
array('I', [8, 4, 2, 4, 8])
Top answer
1 of 1
2

c_bool is one byte in size and prints 0 for zero and 1 for non-zero. You can see that the size in bytes for the structures are incorrect:

>>> sizeof(Bits)
32
>>> sizeof(Int)
4
>>> sizeof(union)
32

Since Value is a 4-byte integer and all four bytes are non-zero the first four byte-sized c_bool fields in the union print 1.

To specify bit fields correctly, specify a 3rd parameter with the number of bits to use. See Bit fields in structures and unions in the ctypes documentation.

from ctypes import *

class Bits(Structure):
    _fields_ = [('Bit_0', c_uint32, 1),  # Use 1 bit of an unsigned 32-bit integer.
                ('Bit_1', c_uint32, 1),  # etc.
                ('Bit_2', c_uint32, 1),
                ('Bit_3', c_uint32, 1),
                ('Bit_4', c_uint32, 1),
                ('Bit_5', c_uint32, 1),
                ('Bit_6', c_uint32, 1),
                ('Bit_7', c_uint32, 1),
                ('Bit_8', c_uint32, 1),
                ('Bit_9', c_uint32, 1),
                ('Bit_10', c_uint32, 1),
                ('Bit_11', c_uint32, 1),
                ('Bit_12', c_uint32, 1),
                ('Bit_13', c_uint32, 1),
                ('Bit_14', c_uint32, 1),
                ('Bit_15', c_uint32, 1),
                ('Bit_16', c_uint32, 1),
                ('Bit_17', c_uint32, 1),
                ('Bit_18', c_uint32, 1),
                ('Bit_19', c_uint32, 1),
                ('Bit_20', c_uint32, 1),
                ('Bit_21', c_uint32, 1),
                ('Bit_22', c_uint32, 1),
                ('Bit_23', c_uint32, 1),
                ('Bit_24', c_uint32, 1),
                ('Bit_25', c_uint32, 1),
                ('Bit_26', c_uint32, 1),
                ('Bit_27', c_uint32, 1),
                ('Bit_28', c_uint32, 1),
                ('Bit_29', c_uint32, 1),
                ('Bit_30', c_uint32, 1),
                ('Bit_31', c_uint32, 1)]

    def return_dic(self):
        dic = {}
        for field in self._fields_:
            dic[field[0]] = getattr(self, field[0])
        return(dic)

class Int(Structure):
    _fields_ = [('Value', c_uint32)]

class union(Union):
    _fields_ = [('Descriptor', Int),('Bits', Bits)]
        
test = union(Int(0x87654321))
print('{0:b}'.format(test.Descriptor.Value))
dic = test.Bits.return_dic()
for x in dic.keys():
    print('{0} : {1:b}'.format(x,dic[x]))

Output:

10000111011001010100001100100001
Bit_0 : 1
Bit_1 : 0
Bit_2 : 0
Bit_3 : 0
Bit_4 : 0
Bit_5 : 1
Bit_6 : 0
Bit_7 : 0
Bit_8 : 1
Bit_9 : 1
Bit_10 : 0
Bit_11 : 0
Bit_12 : 0
Bit_13 : 0
Bit_14 : 1
Bit_15 : 0
Bit_16 : 1
Bit_17 : 0
Bit_18 : 1
Bit_19 : 0
Bit_20 : 0
Bit_21 : 1
Bit_22 : 1
Bit_23 : 0
Bit_24 : 1
Bit_25 : 1
Bit_26 : 1
Bit_27 : 0
Bit_28 : 0
Bit_29 : 0
Bit_30 : 0
Bit_31 : 1
🌐
GitHub
github.com › pypa › pipenv › issues › 4901
mac m1 python3.7 ModuleNotFoundError: No module named '_ctypes' · Issue #4901 · pypa/pipenv
December 26, 2021 - File "/Users/admin/.pyenv/versions/3.7.10/lib/python3.7/ctypes/__init__.py", line 7, in <module> from _ctypes import Union, Structure, Array ModuleNotFoundError: No module named '_ctypes' Pipfile.lock (cc931a) out of date, updating to (883ee9)... Locking [dev-packages] dependencies...
Author: pypa
🌐
Python
docs.python.org › 2 › library › ctypes.html
15.17. ctypes — A foreign function library for Python — Python 2.7.18 documentation
The field type must be a ctypes type like c_int, or any other derived ctypes type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named x and y, and also shows how to initialize a structure in the constructor: >>> from ctypes import * ...