Home > Software design >  Sharing a common memory in python
Sharing a common memory in python

Time:05-04

Below is code with C implementation.

#include <stdio.h>

union test
{
    int a;
    char c;
};

int main()
{
    union test t1;
    int z = 0x0112;
    t1.a = z;
    return 0;
}

Here memory is shared between a and c value of a is 0x112 value of c is 0x12

How should this be implemented in python Current shown union is for example i need to this for an array of intger

In python below is values received in list.

value = m1.read_registers(0, 100, 3)

value is a LIST of 100

Now i want to extract each element and assign to a new variable

reg1 = value[0]
reg2 = value[1]
'
'
'
reg100 = value[3]

The above requires an iterative loop to update every time. Which consumes an amount of time.

Can this be directly done by sharing memory

value = [reg1 , reg2 , ......,reg100]
value = m1.read_registers(0, 100, 3)
print(reg1)
print(reg2)
'
'

CodePudding user response:

The underlying question, I think, is: "how do I cause a Python variable to refer to some subset of an existing sequence, such that changes are reflected?"

The answer depends on the type of the sequence you are using.

For immutable things like str or bytes the question is trivial; there are no changes to reflect in the first place.

For iterables that don't store all their data up front (such as an open file) you are realistically out of luck. Rework your algorithm so that you don't need this.

For list you are again out of luck.

For your own user-defined sequence types, you can define e.g. your __getitem__ so that it returns some kind of proxy object. (If you are interested in this, please ask a more specific question.)

However, it appears that you are specifically concerned with manipulating a low-level buffer of mutable data, where the buffer is raw bytes and the "references" interpret that data in some way.

For this case, you can use memoryview to create views on an underlying mutable buffer (the simplest choice for the buffer is bytearray). The data "seen" by memoryview will automatically update when the underlying buffer is modified (it does not internally store a copy of data, but instead simply "knows" what part of the buffer it is examining). However, you will still have to do the interpretation whenever you examine one of the memoryview "references".

For example:

test = bytearray(b'abcd')
# Let's start by making a view of the entire data.
a = memoryview(test)
# indexing `a` gives you an individual byte...
a[0] # == 97
# but slicing gives you another view object.
c = a[0:1]
# The representation of the `memoryview` doesn't show the underlying memory.
# We need to do some conversion.
int.from_bytes(a, 'big') # we have to specify endianness, too.
int.from_bytes(c, 'big') # but it works for any amount of bytes.
# We can change the raw data...
test[0] = 0
# and the change is reflected in the int conversion results.
int.from_bytes(a, 'big') # 6447972 rather than 1633837924
int.from_bytes(c, 'big') # 0 rather than 97
# We can also change data via the views.
c[0] = ord('x')
a[1] = ord('y')
test # is now bytearray(b'xycd')

Note that, while slicing a memoryview will give a new memoryview on the same buffer, we cannot get the same results by slicing beforehand - c = memoryview(test[0:1]) would create a new buffer for the slice, and then make a view over that entire buffer.

  • Related