Equivalent C union in python?

Viewed 5659

Say I'm having a following code in C

union u_type
{
    uint32_t data;
    uint8_t  chunk[4];
} 32bitsdata;

32bitsdata.chunk[0] = some number;
32bitsdata.chunk[1] = some number;
32bitsdata.chunk[2] = some number;
32bitsdata.chunk[3] = some number;

printf("Data in 32 bits: %d\n", 32bitsdata.data);

How could I do similar thing in python?

I'm trying to read a binary file (byte by byte) - already got it working, and combining every 3 bytes into one int. Heard struct would do the trick, but I'm not really sure how.

Best,

Henry

4 Answers

You asked about C union, but if your objective is to group 3 bytes into an int, you could use Python struct.unpack instead.

import struct

chunk = bytearray()
chunk.append(0x00)   # some number
chunk.append(0xc0)   # some number
chunk.append(0xff)   # some number
chunk.append(0xee)   # some number

# Convert to a 32-bit unsigned int.
# You didn't specify the byte-order, so I'm using big-endian.
# If you want little-endian instead, replace the '>' symbol by '<'.
data = struct.unpack('>I', chunk)[0]  # unpack returns a tupple, but we only need the first value

print(hex(data))  # the terminal prints 0xc0ffee

If you're doing fancy numerical manipulation, you'd probably want to use the numpy library anyway, so consider the "view" method of numpy's ndarray type. The original ndarray can be viewed and modified via the view-array.

>>> import numpy as np
>>> a = np.uint32([1234567890])
>>> b = a.view(np.uint8)
>>> print(a)
[1234567890]
>>> print(b)
[210   2 150  73]
>>> b[2] = 10
>>> print(*b)
210 2 10 73
>>> print(*a)
1225392850
Related