Python memoryview()

The memoryview() method returns a memory view object of the given argument.

Before we get into what memory views are, we need to first understand about Python's Buffer Protocol.

What is a Buffer Protocol?

Simply said, buffer protocol provides a way to access the internal data of an object. This internal data is a memory array or a buffer.

Buffer protocol allows one object to expose its internal data (buffers) and the other to access those buffers without intermediate copying.

This protocol is only accessible to us at the C-API level and not using our normal code base.

So, in order to expose the same protocol to normal Python code base, memory views are present.


What is a memory view?

Memory view is a safe way to expose the buffer protocol in Python.

It allows you to access the internal buffers of an object by creating a memory view object.


Why buffer protocol and memory views are important?

We need to remember that whenever we perform some action on an object (call a function of an object, slice an array), we (or Python) need to create a copy of the object.

If we have a large data to work with (eg. binary data of an image), we would unnecessarily create copies of huge chunks of data, which serves almost no use.

Using buffer protocol, we can give another object access to use/modify the large data without copying it. This makes the program use less memory and increases the execution speed.


How to expose buffer protocol using memory views?

The memory view objects are created using the syntax:

memoryview(obj)

memoryview() Parameters

The memoryview() constructor takes a single parameter:

  • obj - object whose internal data is to be exposed.
    obj must support buffer protocol (bytes, bytearray)

Return value from memoryview()

The memoryview() method returns a memory view object of the given object.


Example 1: How memoryview() works in Python?

#random bytearray
randomByteArray = bytearray('ABC', 'utf-8')

mv = memoryview(randomByteArray)

# access memory view's zeroth index
print(mv[0])

# create byte from memory view
print(bytes(mv[0:2]))

# create list from memory view
print(list(mv[0:3]))

When you run the program, the output will be:

65
b'AB'
[65, 66, 67]

Here, we created a memory view object mv from the byte array randomByteArray.

Then, we accessed the mv's 0th index 'A' and printed it (which gives the ASCII value - 65).

Again, we accessed the mv's indices from 0 and 1 ('AB') and converted them into bytes.

Finally, we accessed all indices of mv and converted it to a list. Since, internally bytearray stores ASCII value for the alphabets, the output is a list of ASCII values of A, B and C.


Example 2: Modify internal data using memory view

#random bytearray
randomByteArray = bytearray('ABC', 'utf-8')
print('Before updation:', randomByteArray)

mv = memoryview(randomByteArray)

# update 1st index of mv to Z
mv[1] = 90
print('After updation:', randomByteArray)

When you run the program, the output will be:

Before updation: bytearray(b'ABC')
After updation: bytearray(b'AZC')

Here, we updated the memory view's 1st index to ASCII - 90 (Z).

Since, the memory view object mv references the same buffer/memory, updating the index in mv also updates randomByteArray.