Parsing a binary log with zero-copy memoryviews
Each record is a 2-byte length followed by that many bytes. Slicing the memoryview makes windows, not copies, and the open views block resizing until you release them.
A Python list holds pointers to separate objects, while NumPy, array and memoryview use one contiguous block of raw C data that is shared through the buffer protocol. That layout, compiled loops and releasing the GIL in native code are why NumPy is fast.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Create an array('h', [1, 2, 3]) and print its item size, the number of bytes in tobytes() and its sum.
Take a bytes object b"abcdef", build a memoryview, print the bytes of the slice [1:3], whether view.obj is the original object and the length of the view.
Show that memoryview(b"\x01\x00\x02\x00").cast("H") reads the same four bytes as two 16-bit numbers.
Explain it without notes
Give three reasons a NumPy operation is faster than the equivalent Python loop.
What is the buffer protocol, and what does memoryview do with it?
Why does a Python list of a million floats use so much more memory than a NumPy array?
How can native code make multi-threaded Python faster, if the GIL exists?
Expected output
['start', 'user=ada', 'stop']
views point into the original buffer: True
a view sees the change: Start
BufferError: Existing exports of data: object cannot be re-sized
after releasing the views, resizing works: 24