Hàm memoryview() trong Python
Trước khi tìm hiểu chế độ xem bộ nhớ (memory view) là gì, chúng ta cần phải nói qua một chút về bộ đệm giao thức của Python.
Giao thức buffer của Python là gì?
Giao thức buffer cung cấp một cách truy cập dữ liệu nội bộ của một đối tượng. Dữ liệu nội bộ này có thể là một mảng bộ nhớ hoặc buffer.
Giao thức buffer cho phép một đối tượng để lộ ra dữ liệu (buffer) bên trong nó và một đối tượng khác có thể truy cập những buffer ấy mà không cần tới phương thức sao chép trung gian.
Giao thức này chỉ có thể truy cập được tới dữ liệu ở mức C-API và không sử dụng cơ sở code thông thường. Chính vì thế, để hiển thị dữ liệu ở cùng một giao thức với cơ sở code Python thông thường, chúng ta cần tới chế độ xem bộ nhớ.
Chế độ xem bộ nhớ là gì?
Chế độ xem bộ nhớ là cách an toàn để hiển thị giao thức buffer trong Python. Nó cho phép bạn truy cập vào buffer bên trong một đối tượng bằng cách tạo ra một đối tượng memory view.
Tại sao giao thức buffer và chế độ xem bộ nhớ lại rất quan trọng trong Python?
Bất cứ khi nào chúng ta thực hiện các hành động trên một đối tượng (thực thi hàm trên một đối tượng, cắt một mảng…), Python đều tạo ra một bản sao của đối tượng. Điều này sẽ gây hao tổn bộ nhớ, làm chậm quá trình xử lý nếu chúng ta làm việc với lượng dữ liệu lớn.
Bằng cách sử dụng giao thức buffer, chúng ta có thể cho phép một đối tượng truy cập để sử dụng/sửa đổi dữ liệu mà không cần phải sao chép ra thêm một bản. Điều này sẽ giúp chương trình sử dụng ít bộ nhớ hơn và tăng tốc độ xử lý code.
Xem thêm: Hàm property() trong Python
Cú pháp hàm memoryview()
Để hiển thị bộ đệm giao thức bằng memoryview(), chúng ta sử dụng cú pháp:
memoryview(đối tượng)
Tham số hàm memoryview()
Hàm memoryview() chỉ có một tham số duy nhất:
- Đối tượng: Đối tượng chứa dữ liệu mà bạn muốn dùng memoryview() để truy cập. Đối tượng này phải hỗ trợ bộ đệm giao thức (byte, bytearray).
Giá trị trả về từ hàm memoryview()
Hàm memoryview() trả về chế độ xem bộ nhớ của đối tượng.
Ví dụ 1: Hàm memoryview() hoạt động như thế nào trong Python?
#random bytearray
random_byte_array = bytearray('SHARENHANH', 'utf-8')
mv = memoryview(random_byte_array)
# truy cập chỉ số ở vị trí số 0 của memory view
print(mv[0])
# tạo byte từ memory view
print(bytes(mv[0:2]))
# tạo danh sách memory view
print(list(mv))
Khi chạy chương trình, kết quả trả về là:
Xem thêm: Hàm oct() trong Python là gì?
Ở đây, chúng ta tạo ra một chế độ xem bộ nhớ mv từ mảng byte random_byte_array.
Sau đó, chúng ta truy cập vào chỉ số ở vị trí 0 của mv, giá trị của chỉ số này là S. Chỉ số này được in ra theo giá trị trong bảng mã ASCII là 83.
Tiếp theo, chúng ta truy cập vào chỉ số vị trí 0 và 1 của mv, SH, và chuyển chúng thành các byte. Cuối cùng, chúng ta truy cập vào tất cả các chỉ số của mv và chuyển chúng thành một danh sách theo mã ASCII.
Ví dụ 2: Chỉnh sửa dữ liệu với hàm memoryview()
# random bytearray
random_byte_array = bytearray('SHARENHANH', 'utf-8')
print('Trước khi sửa:', random_byte_array)
mv = memoryview(random_byte_array)
# cập nhật chỉ số vị trí số 1 của mv thành U
mv[1] = 85
print('Sau khi sửa:', random_byte_array)
Khi chạy chương trình, kết quả nhận được là:
Trước khi sửa: bytearray(b'SHARENHANH')
Sau khi sửa: bytearray(b'SUARENHANH')
Ở đây, chúng ta cập nhật chỉ số vị trí số 1 của mv từ H thành U, 85 là mã ASCII của U.
Do đối tượng memory view mv tham chiếu cùng một bộ đệm/bộ nhớ nên cập nhật chỉ số trong mv cũng đồng thời cập nhật random_byte_array.