Python3 Func Memoryview
# Python memoryview() Function
The `memoryview()` function is a built-in Python utility used to create a **memory view** object.
A memory view allows Python code to access the internal data buffer of an object that supports the **Buffer Protocol** (such as `bytes` or `bytearray`) directly, without making a copy of the data. This is highly beneficial for performance and memory efficiency when handling large binary datasets, network streams, or file I/O.
---
## Syntax and Parameters
### Syntax
```python
memoryview(obj)
```
### Parameters
* **`obj`**: An object that supports the buffer protocol. Common built-in types include `bytes` and `bytearray`.
### Return Value
* Returns a `memoryview` object.
### Key Characteristics
* **Zero-Copy Slicing**: Slicing a `memoryview` returns another `memoryview` object instead of copying the underlying data.
* **Direct Modification**: If the underlying object is mutable (like a `bytearray`), you can modify its contents directly through the memory view.
---
## Code Examples
### Example 1: Creating and Inspecting a memoryview
You can create a `memoryview` from both immutable (`bytes`) and mutable (`bytearray`) objects.
```python
# 1. Create a memoryview from a mutable bytearray
data_mutable = bytearray(b"Hello")
m1 = memoryview(data_mutable)
print(m1) # Output:
# 2. Create a memoryview from immutable bytes
data_immutable = b"World"
m2 = memoryview(data_immutable)
# Accessing elements returns the ASCII integer value of the character
print(m2) # Output: 87 (ASCII code for 'W')
# 3. Slicing a memoryview returns a new memoryview (zero-copy)
sliced_m = m2[0:3]
print(sliced_m) # Output:
print(sliced_m.tobytes()) # Output: b'Wor'
```
**Expected Output:**
```text
87
b'Wor'
```
**Code Analysis:**
* Creating a memory view does not duplicate the string buffer in memory.
* Accessing an index (e.g., `m2`) returns the byte value as an integer.
* Slicing a memory view returns a new memory view pointing to the specified slice of the original buffer without copying it.
---
### Example 2: Modifying Data in Place (Mutable Objects Only)
When the underlying buffer is mutable, you can write to the `memoryview` to modify the original object directly.
```python
# Create a mutable bytearray
data = bytearray(b"Hello")
m = memoryview(data)
# Modify a single element in-place
m = 74 # ASCII code for 'J'
print(data) # Output: bytearray(b'Jello')
# Modify a slice in-place
m[1:5] = b"abcd"
print(data) # Output: bytearray(b'Jabcd')
# Convert the memoryview back to a bytes object
binary_data = b"\x01\x02\x03\x04"
m_bytes = memoryview(binary_data)
print(m_bytes.tobytes()) # Output: b'\x01\x02\x03\x04'
```
**Expected Output:**
```text
bytearray(b'Jello')
bytearray(b'Jabcd')
b'\x01\x02\x03\x04'
```
**Code Analysis:**
* Changing `m` to `74` directly alters the original `data` variable to `"Jello"`.
* Assigning a slice `m[1:5] = b"abcd"` updates the rest of the buffer.
* The `.tobytes()` method allows you to export the buffer's contents back into a standard `bytes` object.
---
## Key Considerations
1. **Mutability Constraints**: You cannot modify a `memoryview` if the underlying object is immutable (e.g., a `bytes` object). Attempting to do so will raise a `TypeError`.
```python
m = memoryview(b"Hello")
m = 74 # TypeError: cannot modify read-only memory
```
2. **Size Constraints**: When modifying a slice of a mutable `memoryview`, the replacement data must be of the exact same size as the slice being replaced.
```python
data = bytearray(b"Hello")
m = memoryview(data)
m[1:3] = b"xyz" # ValueError: memoryview assignment: lvalue and rvalue have different structures
```
3. **Memory Release**: You can explicitly release the buffer resources held by the memory view using the `.release()` method or by using a `with` statement context manager.
```python
with memoryview(bytearray(b"test")) as m:
m = 116 # 't'
# Buffer is automatically released here
```
YouTip