Функція memoryview() в Python повертає об’єкт представлення пам’яті із вказаного об’єкта. Наприклад:
|
1 2 3 4 5 6 7 8 9 |
x = memoryview(b"Hello") print(x) # Повертаємо Unicode першого символу print(x[0]) # Повертаємо Unicode другого символу print(x[1]) |
Результат:
<memory at 0x14ab8fe6ba00>
72
101
Перш ніж ми перейдемо до того, що таке представлення пам’яті, спочатку нам потрібно розібратися з тим, що таке буферний протокол у Python.
Буферний протокол у Python
Буферний протокол надає спосіб доступу до внутрішніх даних об’єкта. Ці внутрішні дані є масивом пам’яті або буфером. Буферний протокол дозволяє одному об’єкту надавати свої внутрішні дані (буфери), а іншому – отримувати доступ до цих даних без проміжного копіювання.
Цей протокол доступний на рівні C-API та не використовує стандартну кодову базу. Тому, щоб представити один і той же протокол для звичайної кодової бази Python, існують представлення пам’яті.
Що таке представлення пам’яті?
Представлення пам’яті — це безпечний спосіб розкрити буферний протокол в Python, який дозволяє отримати доступ до внутрішніх буферів об’єкта шляхом створення об’єкта представлення пам’яті.
Чому буферний протокол та представлення пам’яті важливі?
Потрібно пам’ятати, що кожного разу, коли ми виконуємо будь-яку дію над об’єктом (викликаємо функцію об’єкта, обрізаємо масив), Python необхідно створити копію об’єкта.
Якщо у нас є великі дані для роботи (наприклад, двійкові дані картинки), ми будемо створювати копії величезних фрагментів даних, які будуть марними. Використовуючи буферний протокол, ми можемо надати об’єкту доступ для використання/зміни великих даних без копіювання. Це змусить програму використовувати менше пам’яті та збільшить швидкість її виконання.
Синтаксис функції memoryview()
|
1 |
memoryview(obj) |
Параметри функції memoryview()
Функція memoryview() приймає один параметр:
obj — об’єкт, внутрішні дані якого повинні бути розкриті. obj має підтримувати буферний протокол (байти, байтовий масив).
Значення, яке повертає функція memoryview()
Функція memoryview() повертає об’єкт представлення пам’яті.
Приклад №1: Як працює функція memoryview() у Python?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Випадковий байтовий масив random_byte_array = bytearray('ABC', 'utf-8') mv = memoryview(random_byte_array) # Отримуємо доступ до представлення пам'яті за нульовим індексом print(mv[0]) # Створюємо байт з представлення пам'яті print(bytes(mv[0:2])) # Створюємо список з представлення пам'яті print(list(mv[0:3])) |
Результат:
65
b'AB'
[65, 66, 67]
Тут ми створили об’єкт представлення пам’яті mv з байтового масиву random_byte_array. Потім отримали доступ за нульовим індексом mv до елемента 'A', і вивели його (ASCII-значення якого дорівнює 65) на екран.
Ми знову отримали доступ до індексів mv від 0 до 1, 'AB', і конвертували їх у байти. Зрештою, ми отримали доступ до всіх індексів mv та конвертували їх у список. Оскільки всередині байтовий масив зберігає значення ASCII, результат є списком ASCII-значень 'A', 'B' і 'C'.
Приклад №2: Зміна внутрішніх даних за допомогою представлення пам’яті
|
1 2 3 4 5 6 7 8 9 |
# Випадковий байтовий масив random_byte_array = bytearray('ABC', 'utf-8') print('Before updation:', random_byte_array) mv = memoryview(random_byte_array) # Оновлюємо перший індекс mv на Z mv[1] = 90 print('After updation:', random_byte_array) |
Результат:
Before updation: bytearray(b'ABC')
After updation: bytearray(b'AZC')
Тут ми оновили перший індекс представлення пам’яті до 90 (ASCII-значення Z). Оскільки об’єкт представлення пам’яті mv посилається на той самий буфер/пам’ять, оновлення індексу mv також оновлює random_byte_array.
