Python memoryview example | Python memoryview() Function
Python memoryview objects allow Python code to access the internal data of an object that supports the buffer protocol without copying. Python memoryview() function allows direct read and writes access to an object’s byte-oriented data without needing to copy it first.
Before we deep dive into memory view, we first need to understand about buffer protocol in Python.
#Python Buffer Protocol
It is a protocol that provides a way to access the internal data of an object. The internal data can be a memory array or a buffer. This protocol allows one object to expose its data to other objects and that other objects access those data (buffer) without intermediate copying.
But the problem is, if we cannot access this protocol with the standard code base, this is accessible to us at the C-API level. So, in python, if we want to expose the same protocol in python, we need to use memoryview.
#What is memory view
A memory view is a safe way to expose that buffer protocol. It allows us to access the internal buffers of an object by creating a memory view object in Python.
Here, obj is the internal data to be exposed. But it must support the buffer protocol.
The memoryview() function returns the memory view object of the given object.
See the following code example.
# app.py # Creating a random byte array rarray = bytearray('XYZ', 'utf-8') # getting memory view mview = memoryview(rarray) # Printing memory view's 0th index print(mview) # Now create a list of memory view print(list(mview[0:3])) # Create one tuple of memory view print(tuple(mview[0:3]))
See the output.
88 [88, 89, 90] (88, 89, 90)
Now we will see how can we modify internal data using memoryview.
See the second example.
# app.py # This program will show how we can # Modify internal data using Memory View # Creating a byte array rarray = bytearray('ABC', 'utf-8') # Printing the array before update print(rarray) # Creating memory view mv = memoryview(rarray) # Now we will update one value of Memory View mv = 70 # Now printing updated Byte Array print(rarray)
See the output.
In the above program, first, we are creating the byte array.
Then we are creating the memoryview and update the memoryview and now printing the array again to see the difference.
#Why buffer protocol and memoryviews are imps
Python memoryviews are useful is because they can be sliced without copying the underlying data, unlike bytes/str.
If we have large data to work with (e.g., binary data of an image), we would unnecessarily create copies of huge chunks of data, which serves almost no use.
Using the 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.
The memoryview objects are great when you need subsets of binary data that only need to support indexing.
Instead of having to take the slices (and create new, potentially large) objects to pass to another API, you can take the memoryview object.
One such API example would be a struct module.
Instead of passing in the slice of the large bytes object to parse out packed C values, you pass in the memoryview of just the region you need to extract values from.
The memoryview objects, in fact, support struct unpacking natively; you can target a region of the underlying bytes object with the slice, then use .cast() to ‘interpret’ the underlying bytes as long integers, or floating-point values, or n-dimensional lists of integers.
This makes for very efficient binary file format interpretations, without having to create more copies of the bytes.
Finally, Python memoryview() function example is over.